Here is my code & probelm.
static Throwable t= null;
static String responseFromServer = "";
static Activity a ;
static Handler mHandler = new Handler();
public static String sendToServer(final Activity act, final String data)
{
progDailog = ProgressDialog.show(act, "", " Please wait...", true);
progDailog.setCancelable(true); //BUT this not displaying
Thread th = new Thread()
{
public void run(){
try{
// .........code ... SENDING data to server
responseFromServer = httpclient.execute(httppost, new BasicResponseHandler()).trim();
mHandler.post(showResponse);
}
catch (Exception e)
{
t = e;
e.printStackTrace();
progDailog.dismiss();
mHandler.post(exception);
}
}
};
th.start();
th.join();
return responseFromServer;
}
private static Runnable showResponse = new Runnable()
{
public void run(){
Toast.makeText( a, responseFromServer, Toast.LENGTH_SHORT).show();
progDailog.dismiss();
}
};
private static Runnable exception = new Runnable()
{
public void run(){
Toast.makeText( a, t + " ", Toast.LENGTH_SHORT).show();
progDailog.dismiss();
}
};
Why progressdialog is not getting displayed ?
And Where is the correct place to display it ?
progressDialog.show() can be executed only from the UI thread.
just do the following:
instead of:
progDailog = ProgressDialog.show(act, "", " Please wait...", true);
use this code:
a.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog = ProgressDialog.show(act, "", " Please wait...", true);
}
});
same thing with the dismiss() method
You should make use of AsyncTask other than using Threads. The UI can be handled only from the UI thread. You can not handle the UI thread from the other threads.
For more information on this please read my blog at below link
http://pavandroid.blogspot.in/2010/09/how-to-create-calendar-in-android.html
Related
I have an application that get user input(name and number) , then scanning QR code , and on a press of a button it send the data to my server and get replay from it.
everything is working now as it should.(I can see the message for the server as string when I'm in debug mode).
but I can't see the toast - it doesn't shown
why?
this is the class I have in the ScanActivity.java
public class ScannedBarcodeActivity extends AppCompatActivity {
SurfaceView surfaceView;
TextView txtBarcodeValue;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
private static final int REQUEST_CAMERA_PERMISSION = 201;
Button btnAction;
String intentData = "";
String ServerReply;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_barcode);
initViews();
}
private void initViews() {
txtBarcodeValue = findViewById(R.id.txtBarcodeValue);
surfaceView = findViewById(R.id.surfaceView);
btnAction = findViewById(R.id.btnAction);
btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (intentData.length() > 0) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String server_ip = "My.Server.Public.IP";
int server_port = 9999;
String messageStr = intentData + "!" + phone +"!"+ name+"!##";
Socket clientSocket = new Socket(server_ip, server_port);
PrintWriter mBufferOut = new PrintWriter((new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))), true);
BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
mBufferOut.println(messageStr);
ServerReply = mBufferIn.readLine();
mBufferIn.close();
//see why this is not working - can;t see the toast
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_LONG).show();
clientSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
// Toast.makeText(getApplicationContext(),ServerReply,Toast.LENGTH_LONG).show();
thread.start();
}
Toast.makeText(getApplicationContext(),ServerReply,Toast.LENGTH_LONG).show();
SystemClock.sleep(1000); //ms
Toast.makeText(getApplicationContext(),"Going to Main Page now",Toast.LENGTH_LONG).show();
finish();
}
// }
});
}
this is the how it's look after what you told me to do :(still doesn't work , and for some reason it "skip" the toast part)
public class ScannedBarcodeActivity extends AppCompatActivity {
SurfaceView surfaceView;
TextView txtBarcodeValue;
private BarcodeDetector barcodeDetector;
private CameraSource cameraSource;
private static final int REQUEST_CAMERA_PERMISSION = 201;
Button btnAction;
String intentData = "";
boolean isEmail = false;
String ServerReply;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan_barcode);
initViews();
}
private void initViews() {
txtBarcodeValue = findViewById(R.id.txtBarcodeValue);
surfaceView = findViewById(R.id.surfaceView);
btnAction = findViewById(R.id.btnAction);
;
btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (intentData.length() > 0) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String server_ip = "My.Server.IP";
int server_port = 9999;
String messageStr = intentData + "!" + phone +"!"+ name+"!##";
Socket clientSocket = new Socket(server_ip, server_port);
PrintWriter mBufferOut = new PrintWriter((new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))), true);
BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
mBufferOut.println(messageStr);
ServerReply = mBufferIn.readLine();
mBufferIn.close();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_SHORT).show();
}
});
clientSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
thread.start();
}
SystemClock.sleep(1000); //ms
finish();
}
// }
});
}
All the UI rendering should be done on main thread, you can use view handler to do that
v.post(new Runnable(){
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_LONG).show();
});
This will execute on UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_SHORT).show();
}
});
Your toast is coming from a background thread, it needs to be executed on the main/UI thread
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_LONG).show();
}
});
1) You have to write toast in UI thread. like blow
// you can write toast in UI thread like this
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_LONG).show();
}
});
2) You have to make sure intentData.length() is not 0 ( if your intentData is empty then your thread will never execute, be sure about that.)
if (intentData.length() > 0) {...}
3) And also make sure your code not given any exception before showing your toast message [handle your exception in catch block like following]
catch (Exception e){
Log.e("Exception","your exception is "+e.toString());
}
Hope it helps you.
Toast can't be run on other than the UI thread, you can use
runOnUiThread(new Runnable() {
#Override
public void run() {
//see why this is not working - can;t see the toast
Toast.makeText(getApplicationContext(),"inside the thread",Toast.LENGTH_LONG).show();
}
});
I have try to update my TextView in Thread, but not able to do, below code shows my try
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
String add = null;
public void run() {
add = Util.getLocationCityName(String.valueOf(ltlng.latitude),String.valueOf(ltlng.longitude));
handler.post(new Runnable() {
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
i can able to get the add value which is inside handler but values are not update to my textview, dont know what mistake i have done
Try to init Handler with looper
final Handler handler = new Handler(Looper.getMainLooper());
Also you can try :
private LooperThread mLooperThread;
class LooperThread extends Thread
{
public Handler mHandler;
public void run()
{
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
vImei.setText(msg.getData().getString("ADD"));
}
};
Looper.loop();
}
}
create Looper :
mLooperThread = new LooperThread();
mLooperThread.start();
and when you need to update :
Bundle bundle = new Bundle();
bundle.putString("ADD", add);
Message msg = Message.obtain();
msg.setData(bundle);
mLooperThread.mHandler.sendMessage(msg);
//Global Initialize
String add = "";// not null
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
add = Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
handler.post(new Runnable() {
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
I hope it helps you.. :)
An other solution which solves your problem is the usage of an AsyncTask
AsyncTask<Void, Void, String> asyncTask = new AsyncTask<Void, Void, String>(){
#Override
protected String doInBackground(Void... params) {
// runs on its own thread
return Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// runs on the UI Thread to Update your Views
LogUtil.d("add" + result);
vImei.setText(result);
}
};
asyncTask.execute();
Please try this,
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
String add = null;
public void run() {
add = Util.getLocationCityName(
String.valueOf(ltlng.latitude),
String.valueOf(ltlng.longitude));
runOnUiThread(new Runnable(){
public void run() {
LogUtil.d("add" + add);//i can get the add value
vImei.setText(add);
}
});
}
};
new Thread(runnable).start();
When the user clik on Register Button, a Custom Dialog box appear and the user move to the menu. But in my case, the Costum Dialog appear just for one second and then the user pass to the next layout.
How to set a time for the Custom Dialog please ?
Here my code :
buttonRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
new Thread(new Runnable() {
#Override
public void run() {
final String name = inputName.getText().toString();
final String mail = inputEmail.getText().toString();
final String password = inputPassword.getText()
.toString();
PatientFunctions patientFunction = new PatientFunctions();
json = patientFunction.registerPatient(name, mail,
password);
try {
if (json.getString(KEY_SUCCESS) != null) {
String res = json.getString(KEY_SUCCESS);
if (Integer.parseInt(res) == 1) {
Intent main = new Intent(
getApplicationContext(), Main.class);
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(main);
finish();
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
CustomizeDialog customizeDialog = new CustomizeDialog(RegisterPatient.this);
customizeDialog.show();
Handler handler = null;
handler = new Handler();
handler.postDelayed(new Runnable(){
public void run(){
customizeDialog.cancel();
customizeDialog.dismiss();
}
}, 3000);
}
});
There are many good options including AlarmManager, Timer & TimerTask
You can use a handler too like so:
Handler handler = null;
handler = new Handler();
handler.postDelayed(new Runnable(){
public void run(){
customdialog.cancel();
customdialog.dismiss();
}
}, 500);
the best way to do these kind of process is to use AsyncTask class
and override onPreExecute and doInBackground and onPostExecute
see the official guide
implement the doInBackground() callback method, which runs in a pool of background threads. To update your UI, you should implement onPostExecute(), which delivers the result from doInBackground() and runs in the UI thread, so you can safely update your UI. You can then run the task by calling execute() from the UI thread
private class Registration extends AsyncTask<String, Void, String>{
CustomizeDialog customizeDialog;
#Override
protected void onPreExecute() {
// show ur dialog
customizeDialog = new CustomizeDialog(RegisterPatient.this);
customizeDialog.show();
}
#Override
protected String doInBackground(String... params) {
final String name = params[0];
final String email = params[1];
final String password = params[2];
PatientFunctions patientFunction = new PatientFunctions();
json = patientFunction.registerPatient(name, mail,
password);
try {
if (json.getString(KEY_SUCCESS) != null) {
String res = json.getString(KEY_SUCCESS);
return res;
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(String result) {
if (Integer.parseInt(res) == 1) {
if(customizeDialog != null)
customizeDialog.dismiss();
Intent main = new Intent(
getApplicationContext(), Main.class);
main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//move to the next activity
startActivity(main);
finish();
}
}
}
Edit
and then execute it what ever you want
buttonRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final String name = inputName.getText().toString();
final String mail = inputEmail.getText().toString();
final String password = inputPassword.getText()
.toString();
new Registration().execute(name,mail,password);
}
});
This is my scenario. A class A implements Runnable. When user click a button, there will show a progress dialog and call the method searchMap() to search an address. The dialog dismisses after 10 seconds. I really misunderstand how to execute the run() method. this is my creepy code.
public class AddLocationMapActivity extends MapActivity implements Runnable {
private ProgressDialog progressDialog;
private MyHandler myHandler;
private Message msg;
#Override
public void run() {
mapCurrentAddress();
}
public void mapLocation(View v) // click event here{
progress();
Thread thread = new Thread(this);
thread.start();
}
private class MyHandler extends Handler{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
case NOT_OK_MESSAGE: // Fail
alert(AddLocationMapActivity.this, message());
progressDialog.dismiss();
break;
case OK_MESSAGE: // Success
found(); // Point to the appropiate address
progressDialog.dismiss();
break;
case EXPTION_MESSAGE: // Exception
alert(AddLocationMapActivity.this, "Unexpected error");
progressDialog.dismiss();
break;
}
}
}
protected void mapCurrentAddress() {
String addressString = addressText.getText().toString();
Geocoder g = new Geocoder(this);
List<Address> addresses;
myHandler = new MyHandler();
msg = myHandler.obtainMessage();
try {
addresses = g.getFromLocationName(addressString, 1);
if (addresses.size() > 0) {
//address = addresses.get(0);
msg.what = OK_MESSAGE;
myHandler.sendEmptyMessage(OK_MESSAGE);
} else {
// show the user a note that we failed to get an address
myHandler.sendEmptyMessage(NOT_OK_MESSAGE);
}
} catch (IOException e) {
// show the user a note that we failed to get an address
//e.printStackTrace();
myHandler.sendEmptyMessage(EXPTION_MESSAGE);
}
}
private void progress() {
progressDialog = ProgressDialog.show(this,
"Checking", "Contacting Map Server");
Thread progressThread = new Thread();
progressThread.start();
}
}
When click event occurs, the program fails with exception Uncaught Handler
here's a little bit of my threading code that doesn't give away too much...
progress = ProgressDialog.show(this, "", "Loading...", true);
new Thread(new Runnable() {
#Override
public void run()
{
// get some network content
Chooser.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
// update the UI
}
});
}
}).start();
Implementing a Thread by providing a new class that extends Thread and overriding its run() method is new to me. I've tried all day to get it to work. Here's my code:
/*
* see http://developer.android.com/reference/java/lang/Thread.html
*/
class threadClass extends Thread {
private Handler mHandler;
private Message mMsg;
// constructor
public threadClass(Handler handler, Message msg) {
// do something like save the Handler reference
mHandler = handler;
mMsg = msg;
}
#Override
public void run() {
// do some background processing, call the Handler?
mHandler.sendMessage(mMsg);
}
}
public Thread passHandlerToThread(Handler handler) {
handler.sendEmptyMessage(10);
Message msg = Message.obtain();
msg.what = 10;
Thread thread = new threadClass(handler, msg);
return thread;
}
private Handler localHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
int what = msg.what;
if (what == 10) Log.i("localHandler", "what: " + what);
}
};
public void startThread() {
Thread thread = passHandlerToThread(localHandler);
thread.start();
}
I call startThread() in my LocalService onCreate() but nothing happens. What am I doing wrong? I was expecting localHandler() to be called twice: once in passHandlerToThread() and again in run().
Do something like this:
private final Handler handler = new Handler();
// toast runnables
final Runnable updateTwitterNotification = new Runnable() {
#Override
public void run() {
dismissProgressSpinner();
Toast.makeText(getBaseContext(), "Tweet sent!", Toast.LENGTH_LONG).show();
}
};
final Runnable updateCreateError = new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(), "Tweet error!", Toast.LENGTH_LONG).show();
}
};
postMessageInThread();
//implementation:
private void postMessageInThread() {
Thread t = new Thread() {
#Override
public void run() {
try {
connectToTwitterService() // or whatever
handler.post(updateTwitterNotification);
} catch (Exception ex) {
Log.e(TAG, "Error sending msg", ex);
handler.post(updateCreateError);
}
}
};
t.start();
}