Is doInBackground Cancelled when dialog dismisses? - android

I have a custom progress dialog within an AsyncTask which acts as a download progress, I want to interrupt doInBackground when my custom cancel button pressed. It seems when the dialog dismisses, doInBackground resumes without any problems!

I want to interrupt doInBackground when my custom cancel button pressed.
=> call cancel() method of your AsyncTask inside the cancel button click event. Now this is not enough to cancel doInBackground() process.
For example:
asyncTask.cancel(true);
To notify that you have cancelled AsyncTask using cancel() method, you have to check whether its cancelled or not using isCancelled() inside doInBackground().
For example:
protected Object doInBackground(Object... x)
{
// do your work...
if (isCancelled())
break;
}

You could call AsyncTask.cancel(true) from the cancel event of the dialog. For this you do need a reference to the AsyncTask, this could be an instance variable initialized when the task is started. Then in the asyncTask.doInBackground() method you can check for isCancelled(), or override the onCancelled() method and stop the running task there.
Example:
//Asynctask instance variable
private YourAsyncTask asyncTask;
//Starting the asynctask
public void startAsyncTask(){
asyncTask = new YourAsyncTask();
asyncTask.execute();
}
//Dialog code
loadingDialog = ProgressDialog.show(ThisActivity.this,
"",
"Loading. Please wait...",
false,
true,
new OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
if (asyncTask != null)
{
asyncTask.cancel(true);
}
}
});
EDIT: If you create the dialog from inside the AsyncTask, the code would not be very different. You probably wouldn't need the instance variable, I think you could call YourAsyncTask.this.cancel(true) in that situation.

Related

Abort AsyncTask within the AsyncTask

How to cancel a AsyncTask from a ProgressDialog implemented within this AsyncTask.
#Override
protected Void doInBackground(Void... params)
{
try
{
FTPHelper ftpHelper = new FTPHelper(_context);
ftpHelper.SincronizarArquivos();
}
catch...
#Override
protected void onPreExecute()
{
_dialog.setMessage("Aguarde, sincronizando arquivos...");
_dialog.setCancelable(false);
_dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancelar", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
// This not works for cancel AsyncTask
cancel(true);
...
Since there is no loop in doInBackground (Void ... params) has as I cancel or return. How can I cancel AsyncTask from ProgressDialog?
Both the dialog and the AsyncTask have a 'cancel' method, so when you call cancel in the dialog it cancels the dialog.
The solution is for the dialog to call the cancel function of the AsyncTask. From the code in the question I can't quite infer the way the dialog and the task are linked in the code, but in essence, if ...
AsyncTask myAT;
Then within the dialog:
myAT.cancel();
Call
MyAsyncTask.this.cancel(true);
inside the Dialog.
Here MyAsyncTask is the name of your AsyncTask subclass.
NOTE: This will work (only) if the Dialog was instantiated inside the AsyncTask

Check if asynctask with Progress Dialog is finished in non activity class

I have a created non activity java class for doing same calculation from different activities. This class has asynctask with progress Dialog in it. In most cases calculation is not the last operation of activity and everything goes fine, but when it is my Progress Dialog goes lost.
Example:
myJavaClass doCalculations= new myJavaClass (SomeActivity.this);
doCalculations.Do(); //<------ method Do has asysctask with Progress Dialog
finish();
result:
java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{2bbf820e V.E..... R......D 0,0-1026,483} not attached to window manager
How can I wait for asynctask to finish and then finish activity?
Additional question: Is using asynctask in non activity class is a bad practice ?
If you want to keep your activity active until the AsyncTask has finished its job, you can define a callback method in the activity that gets called when the task has finished and can react appropriately:
In the Activity:
private boolean finishAfterCurrentTask = false;
public void onTaskFinished() {
if (finishAfterCurrentTask) { // set this to true when running the last task
finish();
}
}
In the AsyncTask:
protected void onPostExecute(Object result) {
progressDialog.dismiss();
activity.onTaskFinished();
}
I'm assuming that you're keeping a reference to the activity in myJavaClass. In case that you're calling the AsyncTask from a non-UI thread, you should probably run the callback (and also all methods involving the dialog) via Activity.runOnUiThread().
As for the second question - if you use an AsyncTask in a class which methods can be called from a thread other than the UI thread, it's necessary to use runOnUiThread() to perform any operations on the UI, such as changing the contents of a view or showing/hiding a dialog, beause onPreExecute() and onPostExecute() are called from the same thread as execute().
On the other hand, if you start the task inside one of the UI callbacks, which are guaranteed to run on the UI thread, you don't need to worry about that.
The AsyncTask has a onPostExecute method you can finish the activity from there
protected void onPostExecute(Long result) {
progressDialog.dismiss();
finish(); // you'll probably have to call finish() with a callback function
}
The onPostExecute method is called when the doInBackground method is finished, on that method you can finish the activity and close the progressdialog

ProgressDialog communicate with AsyncTask in android

Tips or ideas on how ProgressDialog can communicate with asyncTask.
For example when I click the button, the program will validate the input to internet, This is should not be interupted. so I use ProgressDialog.
After progressDialog.dismiss(), I need to refresh the view by calling the asyncTask.
I have tried some ways but it's failed, for example
* I execute asynTask after progressdialog.dismiss().
* put execution asynctask inside dialogbox after progressdialog thread.
in other word, is there any way to tell asynctask that progressdialog has been dismissed. Or is there communication such as message between threads ?
here is the example of my code:
btnPost.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stockProgressDialog = ProgressDialog.show(PostActivity.this,
"Please wait...", "Check the post");
new Thread() {
public void run() {
try{
/* Connect to Internet API */
stockProgressDialog.dismiss();
} catch (Exception e) { }
// Dismiss the Dialog
}
}.start();
new LookUpTask().execute();
}
});
Yes, there is a way to tell asyncTask that progressDialog has been dismissed. you can use one onDismissListener
#Override
public Dialog onCreateDialog(int id){
if(id==DIALOG_PROGRESS_DIALOG){
stockProgressDialog = new ProgressDialog(Main.this);
stockProgressDialog.setTitle("Please wait...");
stockProgressDialog.setMessage("Check the post");
stockProgressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
textView.setText("Waiting the 5 secs...");
myAsyncTask.execute("start it");
//Or myAsyncTask.cancel(true); if you want to interrupt your asyncTask
}
});
return stockProgressDialog;
} else return super.onCreateDialog(id);
}
You can cancel an AsyncTask by calling AsyncTask.cancel(..) and then start up a new AsyncTask. You are not supposed to run the AsyncTask as a parallel activity - it is supposed to be able to run and finish without outside intervention.
Extend async and look into returning a result from doInBackground. onProgress update can dismiss your Progress dialog under control of the async task. Handle the result from doInBackground in onPostExecute.
//create the task
theBackground = new Background();
theBackground.execute("");
--------
private class Background extends AsyncTask<String, String, String>{
protected String doInBackground(String...str ) {
publishProgress("##0");
//do a bunch of stuff
publishProgress(#001);
return("true");
}
protected void onProgressUpdate(String... str ) {
//do stuff based on the progress string and eventually
myProgressDialog.dismiss();
}
protected void onPostExecute(String result) {
}
}
I'm not sure why you're using a thread in one case, but an AsyncTask in another when you could just use two AsyncTasks... Actually, unless I'm missing something, in your case the most straightforward way is to combine the two bits of work into one AsyncTask and simply create and destroy the dialog in the AsyncTask callbacks. In pseudo-code:
onPreExecute
show dialog
doInBackground
do internet stuff
onPostExecute
update views
close dialog
Is there a reason why you're trying to update the views in its own AsyncTask? If you're updating views, you probably need to do the work in the UI thread anyway...

Updating progress dialog in Activity from AsyncTask

In my app I am doing some intense work in AsyncTask as suggested by Android tutorials and showing a ProgressDialog in my main my activity:
dialog = ProgressDialog.show(MyActivity.this, "title", "text");
new MyTask().execute(request);
where then later in MyTask I post results back to activity:
class MyTask extends AsyncTask<Request, Void, Result> {
#Override protected Result doInBackground(Request... params) {
// do some intense work here and return result
}
#Override protected void onPostExecute(Result res) {
postResult(res);
}
}
and on result posting, in main activity I hide the dialog:
protected void postResult( Result res ) {
dialog.dismiss();
// do something more here with result...
}
So everything is working fine here, but I would like to somehow to update the progress dialog to able to show the user some real progress instead just of dummy "Please wait..." message. Can I somehow access the progress dialog from MyTask.doInBackground, where all work is done?
As I understand it is running as separate Thread, so I cannot "talk" to main activity from there and that is why I use onPostExecute to push the result back to it. But the problem is that onPostExecute is called only when all work is already done and I would like to update progress the dialog in the middle of doing something.
Any tips how to do this?
AsyncTask has method onProgressUpdate(Integer...) that you can call each iteration for example or each time a progress is done during doInBackground() by calling publishProgress().
Refer to the docs for more details
you can update from AsyncTask's method onProgressUpdate(YOUR_PROGRESS) that can be invoked from doInBackground method by calling publishProgress(YOUR_PROGRESS)
the data type of YOUR_PROGRESS can be defined from AsyncTask<Int, YOUR_PROGRESS_DATA_TYPE, Long>

Progress Dialog on open activity

I have a problem with progress dialog on opening an activity (called activity 2 in example).
The activity 2 has a lot of code to execute in this OnCreate event.
final ProgressDialog myProgressDialog = ProgressDialog.show(MyApp.this,getString(R.string.lstAppWait), getString(R.string.lstAppLoading), true);
new Thread() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
showApps();
}
});
myProgressDialog.dismiss();
}
}.start();
The showApps function launch activity 2.
If I execute this code on my button click event on activity 1, I see the progress, but she doesn't move and afeter I have a black screen during 2 or 3 seconds the time for android to show the activity.
If I execute this code in the OnCreate of Activity2 and if I replace the showApps by the code on OnCreate, Activity1 freeze 2 seconds, I don't see the progress dialog, and freeze again 2 seconds on activity 2 before seeing the result.
I had the same issue and using an AsyncTask is working for me.
There are 3 important methods to override in AsyncTask.
doInBackground : this is where the meat of your background
processing will occur.
onPreExecute : show your ProgressDialog here ( showDialog )
onPostExecute : hide your ProgressDialog here ( removeDialog or dismissDialog
)
If you make your AsyncTask subclass as an inner class of your activity, then you can call the framework methods showDialog, dismissDialog, and removeDialog from within your AsyncActivity.
Here's a sample implementation of AsyncTask:
class LoginProgressTask extends AsyncTask<String, Integer, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
try {
Thread.sleep(4000); // Do your real work here
} catch (InterruptedException e) {
e.printStackTrace();
}
return Boolean.TRUE; // Return your real result here
}
#Override
protected void onPreExecute() {
showDialog(AUTHORIZING_DIALOG);
}
#Override
protected void onPostExecute(Boolean result) {
// result is the value returned from doInBackground
removeDialog(AUTHORIZING_DIALOG);
Intent i = new Intent(HelloAndroid.this, LandingActivity.class);
startActivity(i);
}
}
AFAIK you cannot preload any activity with progress dialog displayed. Are you testing on a real device or in emulator?
I've seen workarounds that opened an activity with a ViewFlipper having a progress animation in the center, and in the next View, it was loaded an activity, but it's not something is recommended and hard to implement to work as you wish.
GeeXor
I would suggest you to avoid performing lots of operations in Activity 2's OnCreate.Writing lots of operations in OnCreate is a reason for the black screen between activities.So perform those operations asynchronously using AsyncTask or in a Thread (or write them in onStart if they are unavoidable).
The other suggestion is to start another progressDialog in activity 2's onCreate which will run until all of your data is loaded & user will know that something is happening in background.
this is what i would do. create a handler on the ui thread, start the background processing thread and then show the progressdialog. when the background thread has finished it's work get it to post a runnable on the ui thread via the handler to dismiss the dialog.

Categories

Resources