2

I have created an App which requires to run a operation in background for quite some time suppose 10 - 15 mins.

I am running this operation in An AsyncTask. So during this time the user is minimizing the Screen and using his other apps in his phone as usual.

When this operation is started I am creating a Progress Dialog box and then keep updating it regularly.

But this is the error which I am receiving sometimes very rarely once the operation is over

Fatal Exception: java.lang.IllegalArgumentException View=DecorView@1234567[ABC:] not attached to window manager PackageName 

And this is the detailed stack log

Fatal Exception: java.lang.IllegalArgumentException View=DecorView@1234567[ABC:] not attached to window manager PackageName

 at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:508) at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:417) at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:136) at android.app.Dialog.dismissDialog(Dialog.java:446) at android.app.Dialog.dismiss(Dialog.java:429) at android.app.Dialog.cancel(Dialog.java:1353) at PACKAGENAME at android.app.Activity.runOnUiThread(Activity.java:6078) at PACKAGENAME at PACKAGENAME at android.os.AsyncTask.finish(AsyncTask.java:667) at android.os.AsyncTask.-wrap1(AsyncTask.java) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:684) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6823) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1557) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445) 

To my knowledge this error is because the Android OS wanted to release some memory hence my App was closed since this was not visible to the user. But is there any way to tackle this thing?

Any help would be really appreciated.

EDIT: This is the code which I am using

 public class load extends AsyncTask<Void, Void, Void> { @Override public Void doInBackground(Void... voids) { for(int i=0;i<number;i++){ PerformSomeOperation(); UpdateTheProgress(); } return null; } @Override protected void onPostExecute(Void n) { runOnUiThread(new Runnable() { @Override public void run() { mProgressDialog.cancel(); CreateAnotherDialog();//This dialog is created to show the user completion of the progress. } }); } 
7
  • You should create a FOREGROUND service that will perform the task to ensure it's not killed by the system. Commented Jul 15, 2018 at 21:26
  • @Pawel Thans for the answer. Suppose the service is not killed but is it possible for the activity to be killed by the Android OS? Commented Jul 15, 2018 at 21:28
  • Please show the relevant code. Commented Jul 15, 2018 at 21:32
  • @Anatolii Will shortly update with the code. Commented Jul 15, 2018 at 21:53
  • @Anatolii Have updated the question with the code. Can you please have a look. Commented Jul 15, 2018 at 22:18

2 Answers 2

1

You're having this crash because you're trying to update the UI when it's in the background so your Activity could be destroyed at that point. By the way, onPostExecute runs your code on the main thread already but as you're sending a separate message to the main looper you're postponing your logic a bit which can also cause a problem. Moreover, But the main question - why to update the UI if it's not visible to the user anyways?

Also, because you're using the AsyncTask as an inner class you may leak (though temporarily) your Activity object as it's referenced implicitly by the task.

From Android Documentation:

AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.

So, don't use AsyncTasks for long-running operations. A better approach would be to use:

  1. IntentService together with BroadcastReceiver to communicate with your Activity / Fragment (in API >= 26 you should use JobIntentService as IntentService may misbehave due to new restrictions on background services).
  2. RxAndroid (or just ExecutorService/Thread) together with Architecture-Components (more specifically with LiveData) - this way a result of your task can be cached or it can survive the config change.

My personal favourite is option 2.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the answer. How is it possible to save/cache a ArrayList. Also Is it possible to run two Intent Service at the same time?
Your answer is very detailed and helpful. Thanks once again
@RajeshK You're welcome. 1) To save your ArrayList where? If you're talking about sending it from your Service to Activity then you can do this by using Intent' and putting it into Serializable (putSerializable() method) 2) It's possible to run several IntentServices in parallel. 2)
Can you please help to answer this question also stackoverflow.com/questions/51508046/…
1

There are few things to say: (1) the "onPostExecuted()" method is already executed on the UiThread/MainThread, so "runOnUiThread()" is not required. (2) if the Activity is minimized/destroyed when the Asynctask reach the final pass you get an Exception. So you have to check if the View is attached using "View. IsAttachedToWindow()" before execute some GUI methods like "mProgressDialog.cancel()". (3) you have to create a Thread or a Service to do a task that should run/work more than few seconds, or the System could kill it at anytime.

4 Comments

Thanks for the points.1) But many time I had received a error on onPostExecuted() hence I use runOnUiThread() always. 3) Suppose if I create a service to run the operation, but will the activity be destroyed?
The Service or Thread runs even if the Activity is destroyed exactly as an Asynctask does. A Service can be automatically restarted by the System if the STICKY flag is used on it, and however a Sticky Service is one of the latest thing killed by the System if Memory is required, so the kill procedure is very rare to occurs.
Thanks for the help. But @Anatolii seems to solve the issue.
Sorry for that but his answer is more detailed for me to understand and provides a complete solution. Sorry once again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.