How to react to the end of a Thread - android

I have a log-in-Thread and while it is running i want to show up kind of a "loading-circle". So how can i recognize when the thread ends and react to it?
loadingcicle.setVisibility(View.VISIBLE);
Thread t = new Thread(new Einloggen());
t.start();
//and at the end
loadingcicle.setVisibility(View.GONE);

You probably want to use the asynctask pattern.
http://developer.android.com/reference/android/os/AsyncTask.html
something like
new AsyncTask<Void, Void, Void>() {
protected void onPreExecute() {
showProgress(true);
}
protected void void onPostExecute(Void result) {
hidProgress(true);
}
protected Void doInBackground(Void...voids) {
doMyBackgroundStuff();
}
}.executeOnExexutor(AsyncTask.THREAD_POOL_EXECUTOR);
of course you should be aware of activity lifecycle events and check that you are at least started or resumed before updating the ui.

You could instantiate a Handler object on your activity and pass it to your Einloggen class. So with this handler you can call Handler.post() to execute commands on UIThread.
Look at this reference: http://developer.android.com/reference/android/os/Handler.html

final android.os.Handler mHandler = new android.os.Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what){
case 1:
//
Toast.makeText(context,"Responded !!!",Toast.LENGTH_LONG).show();
break;
}
return false;
}
});
new Thread(new Runnable() {
#Override
public void run() {
//do whatever you want here
mHandler.sendEmptyMessage(1);
}
}).start();

Related

Starting a runnable in background thread

I have, to my knowledge, implemented a runnable which is created on a new thread. However, the thread does not seem to be running in the background, and the actions taken inside the runnable are stalling the UI with heavy actions.
See below:
custListLoadThread = new Thread(loadRunnable);
custListLoadThread.run();
private Runnable loadRunnable = new Runnable()
{
#Override
public void run()
{
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
Gen.popup("TEST"); // Creates a toast pop-up.
// This is to know if this runnable is running on UI thread or not!
try
{
customers = Db.BasicArrays.getCustomers(CustomApp.Session.businessCode, empId);
runOnUiThread(new Runnable() {
#Override
public void run() {
populate();
setCustListVisible(true);
loading = false;
}
});
}
catch (final Exception ex)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
Gen.popup(ex.getMessage());
}
});
}
}
};
However this code does not run in the background, it still seems to run on the UI thread. I have placed the line Gen.popup("TEST"); to make sure of this (calling a toast pop up in a non-UI thread should cause an error).
Any ideas as to why this runnable isn't running in the background?
custListLoadThread = new Thread(loadRunnable);
custListLoadThread.start();
You need to start the thread, not call the run() method in the current thread.
If you want to execute code on a background thread that does not do something with the UI:
Runnable runnable = new Runnable() {
#Override
public void run() {
//your action
}
};
AsyncTask.execute(runnable);
Of course as written before you can also create a new thread (that is independent from the UI thread):
new Thread(runnable).start();
In your example you want to update UI elements, so better use a AsyncTask (must be called from UI thread!):
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// your async action
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
// update the UI (this is executed on UI thread)
super.onPostExecute(aVoid);
}
}.execute();

Android close activity after thread ends

I have an activity, and a buttonClick where I call a Thread that will POST some JSON to a PHP file. I want the activity to get Closed after the thread ends. How can I do that?
This is my click event:
Button bsave = (Button) findViewById(R.id.button3);
View.OnClickListener eventHandlerx = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
sendJson( urlx, jsonarray);
}
...
And this is my Thread:
private void sendJson(final String urlx, final JSONArray jsonarray) {
Thread t = new Thread() {
public void run() {
Looper.prepare();
...}
...}
}
Where can I call finish() in order to close my activity?
Thank you
You can call finish() from anywhere within the UI thread. You can execute code from within the UI thread by using an AysncTask's onPostExecute (replace your Thread with it) or by starting a Runnable using the Activity's runOnUiThread.
Hope it will help
class SendJson extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//here you can call functionality
}
#Override
protected void onPostExecute(String result) {
//here you can call finish
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Here's an example using Handler since you just want to close the activity:
new Handler().post(new Runnable() {
#Override
public void run() {
//do your stuff here
MyActivity.this.finish();
}
});
But as #dst mentioned, you should use AsyncTask whenever possible.
I did tests
- you can startActivity from non-ui Thread
- you can finish Activity from non-ui Thread
Look at the ACRA project - nice exception handling. In ReportExecutor in line 251 (https://github.com/ACRA/acra/blob/master/src/main/java/org/acra/builder/ReportExecutor.java#L251) activity is started in new thread.
I was too surprised why it is working :)

How to execute an instruction/method immediately after ProgressDialog dismisses?

I am trying to execute the method doSomeWork(); after the ProgressDialog dismisses in my method printing();which seems to be overlapped by the other method and the dialog is not showed up. If I comment method doSomeWork(); the dialog is displayed correctly until the thread is finished.
Here is my method printing();
public void printing()
{
final ProgressDialog printingDialog = ProgressDialog.show(this, "Printing...", "Please wait", true, false);
new Thread(new Runnable() {
#Override
public void run()
{
//something big executing here
}
}).start();
}
He is my method doSomework():
public void doSomeWork(){
Thread receiptPrint = new Thread(new Runnable() {
#Override
public void run() {
//something here
runOnUiThread(new Runnable() {
#Override
public void run() {
//another dialog here
}
});
}
});
}
Here you can see the how I am calling those two methods:
private OnClickListener onClickPrint = new OnClickListener() {
public void onClick(final View v) {
Log.d("Button","Clicked on Print Order Button");
printing();
doSomeWork();
Does anyone know how could I execute doSomeWork() only when printing(); will be completely finished?
This is one of the purposes of an AsyncTask. It would look similar to this:
public void onClick(final View v) {
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
//Show your progress dialog in here
super.onPreExecute();
}
#Override
protected Void doInBackground( Void... params ) {
printing();
return null;
}
#Override
protected void onPostExecute( Void result ) {
//Dismiss your progress dialog here
doSomeWork();
}
}.execute();
}
Instead of using thread you can use asynchronous task. Show the progress dialog in the preexecute method call the printing method inside the background method after completing printing operation call the doSomeWork() inside the postexecute method.
You can use Handler for that in android. for example consider the following piece of code. you can dismiss the dialogs inside handlers. may it work for you.
private void printing(){
Thread receiptPrint = new Thread(new Runnable() {
#Override
public void run() {
retrieveEmails();
runOnUiThread(new Runnable() {
#Override
public void run() {
try{
//here your code executes
//after code executes do following:
uiHandler.sendEmptyMessage(0);
}catch(Exception ex){
errorHandler.sendEmptyMessage(0);
}
}
});
}
});
receiptPrint.start();
}
final Handler uiHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
//here execute doSomeWork()
}
};
final Handler errorHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
//do other stuff
}
};

Android: Handler for AsyncTask

I use AsyncTask in combination with a ProgressDialog.
See my code, I have a problem in onPostExecute.
If the task is running for the first time it get a Null Poiter Exception for progressDialog in handleMessage but calling dismiss() direct would work.
When I turn the phone before onPostExecute is reached, progressDialog.dismiss() does not work. why does the handler not always work?
public class UpdateTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
private Handler handler;
public UpdateTask(Act activity) {
progressDialog = ProgressDialog.show(Activity.this, "Wait",
"Wait");
progressDialog.dismiss();
handler = new Handler(){
#Override
public void handleMessage(Message msg) {
//run on UI Thread
switch( msg.what ){
case MSG:
progressDialog.show();
break;
case DETACH:
progressDialog.dismiss();
break;
}
}
};
}
void detach() {
activity=null;
//problematic
//progressDialog.dismiss();
//handler.sendEmptyMessage(DETACH);
}
#Override
protected Void doInBackground(Void... params) {
handler.sendEmptyMessage(MSG);;
return null;
}
protected void onPostExecute(Void result) {
if (activity==null) {
Log.w("RotationAsync", "onPostExecute() skipped -- no activity");
}
else {
//problematic
// progressDialog.dismiss();
handler.sendEmptyMessage(MSG);
progressDialog = null;
}
}
};
Any reason why you need the Handler inside the AsyncTask? If you want to control your progress dialogue from an AsyncTask using a Handler is the correct way, however, your current Handler would get created and destroyed each time you start a new UpdateTask. If you define your handler outside your AsyncTask, something like:
private Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch( msg.what ){
case MSG:
progressDialog.show();
break;
case DETACH:
progressDialog.dismiss();
break;
}
return false;
}
});
Now you can call handler.sendEmptyMessage(what) from any background thread safely, and the progressDialog will update on the UI thread only. Not a complete fix, and I don't know what int values you have defined for DETACH and MSG. But hopefully it will help. This is the method I use to update any UI element from a background task. Just do a bit more reading about the AsyncTask and updating UI elements.
See https://stackoverflow.com/a/4538370/719212
And you should read about onPreExecute() in Android documentation.

ProgressDialog won't dismiss in Thread

I am new to Android dev, and am trying to solve this problem that has been giving me some frustration. I am trying to close this progressDialog. When I run the app, it displays, the information is fetched, and the UI is updated. However, the dialog is never dismissed.
progDialog = ProgressDialog.show(HomeActivity.this, "", "Fetching info...", true, false);
new Thread(new Runnable() {
public void run() {
fetchInfomation(userID); //fetches information - Works
runOnUiThread(new Runnable() {
public void run() {
setLayoutList(); //updates UI - Works
progDialog.dismiss(); //doesn't seem to close progress dialog
firstView(); //displays prompt - Works
}
});
progDialog.dismiss(); //doesn't close dialog either
}
}).start();
Any ideas?
You can't interact with UI inside an external thread. There is some techniques to do that but it's not necessary.
You can use Handler.
For example:
...
private Handler mHandler;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mHandler = new Handler() {
#Override
public void handleMessage (Message msg) {
switch (msg.what) {
case 0: ...
case 1: ...
}
}
}
}
And:
....
new Thread() {
#Override
public void run() {
... // do your background jobs here
mHandler.sendEmptyMessage(...); // interact with UI
});
}
}.start();
It will be good practice if you do any GUI updates on UI thread. Inside any thread you can run your UI thread where you can do the UI stuffs or else you can go for message handler also which will do the same for you.
Runnable run_in_ui = new Runnable() {
#Override
public void run() {
// do your UI stuffs here
}
};
runOnUiThread(run_in_ui);

Categories

Resources