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
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 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);
}
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.
I have a Button, and upon pressing it, the onClick() would process user's request. However, this takes a little time, so I would like to have a View showing "Please wait, processing..." immediately upon pressing this Button, while its OnClickListener does its thing.
My problem is, this "Please wait, processing..." which I placed at the very beginning of onClick(), only appears AFTER the whole onClick() is done. In other words, after the whole processing is done. So, I was wondering, how do I make a View saying "Please wait, processing..." before the actual processing has begun?
As #Blundell pointed you may process long-running operation on a separate thread to avoid freezing of UI thread. However in Android there's a better alternative for general-purpose Handler which is called AsyncTask. Please refer to this tutorial for details.
You can do this by just using AsyncTask without dealing anything else.
First create new AsyncTask class on "onPreExecute" change ui to show
that you are processing sth
Second do your all backend time consuming job on "doInBackground"
method (do not call any ui updating method from here)
Third change your ui to show that process is finished or whatever you
wanna do.
yourUiButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
new NewTask().execute();
}
});
class NewTask extends AsyncTask<String, Void, Task>{
#Override
protected void onPreExecute() {
super.onPreExecute();
//this part runs on ui thread
//show your "wait while processing" view
}
#Override
protected Task doInBackground(String... arg0) {
//do your processing job here
//this part is not running on ui thread
return task;
}
#Override
protected void onPostExecute(Task result) {
super.onPostExecute(result);
//this part runs on ui thread
//run after your long process finished
//do whatever you want here like updating ui components
}}
Do the processing on another thread so that the UI can show your dialog.
// Show dialog
// Start a new thread , either like this or with an ASyncTask
new Thread(){
public void run(){
// Do your thang
// inform the UI thread you've finished
handler.sendEmptyMessage();
}
}
When the processing is done you will need to callback to the UI thread to dismiss oyur dialog.
Handler handler = new Handler(){
public void handleMessage(int what){
// dismiss your dialog
}
};
AsyncTasks.
Place the displaying of the progress dialog in onPreExecute
Do your thing in doInBackground
Update whatever needs to be updated in the UI, and close the dialog in onPostExecute
You will need something like this
public void onClick(View v){
//show message "Please wait, processing..."
Thread temp = new Thread(){
#Override
public void run(){
//Do everything you need
}
};
temp.start();
}
or if you want it to run in the UIThread (since it is an intensive task, I don't recommend this)
public void onClick(View v){
//show message "Please wait, processing..."
Runnable action = new Runnable(){
#Override
public void run(){
//Do everything you need
}
};
v.post(action);
}
put ur code inside a thread and use a progress dialogue there...
void fn_longprocess() {
m_ProgressDialog = ProgressDialog.show(this, " Please wait", "..", true);
fn_thread = new Runnable() {
#Override
public void run() {
try {
// do your long process here
runOnUiThread(UI_Thread);//call your ui thread here
}catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(null, thread1
"thread1");
thread.start();
}
then close your dialogue in the UI thread...hope it helps..
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...