I have progressDialog, which is used for my AsyncTask, while downloading file. In AsyncTask I have implemented theese methods:
#Override
protected void onCancelled() {
handleOnCancelled(this.result);
super.onCancelled();
}
#Override
protected void onCancelled(String result) {
super.onCancelled(result);
}
In my activty, I am declaring mProgressDialog and giving it onCancelListener:
mProgressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
xml.cancel(true);
}
});
When I press back key, mProgressDialog is closed, onCancel (method above) is called, but Async Task still runs on the background. How to solve it?
Thanks
You need to repeatedly check the boolean isCanceled() within your doInBackground() method. If this method returns true, you should immediately exit any loop or background work being done by the task.
Refer to the docs.
Check for isCanceled() in the async task while you are downloading.
Try This
if(myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING))
{
myAsyncTask.cancel(true);
}
Related
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
I have an AsyncTask that shows a dialog when runing. When i click cancel :
if (isCancelled()) break;
How to display a message in a dialog ( with "ok" button ) when i cancel the asyncTask?
Thanks
AsyncTask has a method just for that
#Override
protected void onCancelled() {
super.onCancelled();
// Show the dialog
}
onCancelled is only called if cancel is called. However note the docs: Runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished.
This means onCancelled will not be called immediately on any thread.
You just have to create an alert dialog and display it in the onCancelled method of AsyncTask
#Override
protected void onCancelled() {
super.onCancelled();
runOnUiThread(new Runnable() {
#Override
public void run() {
dialog.show();
}
});
}
To know on creation of dialog, you can follow this: Alert dialog with a button
I have created an Android Application, in that I want to cancel AsyncTask onPause state of Fragment.
I tried using AsyncTask.cancel(true); but it gives null pointer exception.
#Override
public void onPause()
{
super.onPause();
AsyncTask.cancel(true);
}
Thanks.
task.cancel() will do it. Be sure to include frequent checks to isCancelled() in your onBackground() as well as in onPostExecute() to avoid accessing/updating UI which is no longer there.
public void onActivityPause() {
task.cancel();
}
asyncTask.cancel(true); will change a boolean value only and don't stop your thread.
so you need to "ask" if the async task not cancelled.
example:
#Override
protected Void doInBackground(Void... params) {
while(!isCancelled()){
// do something
}
return null;
}
Strange effect in displaying an AlertDialog inside AsyncTask: if the application is minimized during the execution of the AsyncTask:
private class CheckDeviceConfiguration extends AsyncTask<Void, Void, Boolean> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(ActivitySIPCountrySelection.this, "Title", "working...", true);
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressDialog.dismiss(); //hide progress dialog previously shown
if (!result) {
AlertDialog.Builder dialog = new AlertDialog.Builder(ActivitySIPCountrySelection.this);
dialog.setCancelable(false);
dialog.setMessage("Message");
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
//do something
}
});
dialog.show();
}
}
#Override
protected Boolean doInBackground(Void... params)
Thread.sleep(5000);
return false;
}
}
If I click on my app icon to restore, the UI is not responding and the activity looks a bit darkened (inactive?). Back button has no effect.
Edit:
Someone asks where I call AsyncTask. Well, from the Activity onCreate().
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sip_country_selection);
new CheckDeviceConfiguration().execute();
}
The async task shows correctly a progress dialog and hide it in onPostExecute.
NOTE: AsyncTask manages a thread pool, created with ThreadPoolExecutor. It will have from 5 to 128 threads. If there are more than 5 threads, those extra threads will stick around for at most 10 seconds before being removed. (note: these figures are for the presently-visible open source code and vary by Android release).
Leave the AsyncTask threads alone, please.
Pressing the Home switches you from the app to the home screen, whilst leaving your app running in the background.
When your phone is running low on resources like memory it will start to close apps that are running in the background, so that your phone has enough resources for what you're trying to do now. Games are often amongst the first apps the phone will "kill" to save resources as they often use a lot more memory and CPU than other apps. This is why sometimes your game is still running paused, and sometimes Android has closed it for you.
http://developer.android.com/guide/components/tasks-and-back-stack.html. For more details check tasks and back task.
You can cancel asynctask by calling cancel(true), an interrupt will be sent to the background thread, which may help interruptible tasks. Otherwise, you should simply make sure to check isCancelled() regularly in your doInBackground() method.
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
d.cancel(true);
if(d.isCancelled())
{
System.out.println("Destroyed....");
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
d.cancel(true);
if(d.isCancelled())
{
System.out.println("Destroyed....");
}
}
SO when your activity resumes create a new instance of asynctask and execute again.
http://code.google.com/p/shelves/. Check shelves project by Romain Guy.
http://developer.android.com/reference/android/content/AsyncTaskLoader.html. Also check asynctask loader.
An alternative to asynctask is RoboSpice.
https://github.com/octo-online/robospice.
FAQ's https://github.com/octo-online/robospice/wiki/Advanced-RoboSpice-Usages-and-FAQ.
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...