Java 处理Android关闭应用程序

Java 处理Android关闭应用程序,java,android,memory-management,service,android-asynctask,Java,Android,Memory Management,Service,Android Asynctask,我创建了一个应用程序,它需要在后台运行一段时间(假设10-15分钟) 我正在异步任务中运行此操作。因此,在这段时间内,用户将屏幕最小化,并像往常一样在手机中使用其他应用程序 启动此操作时,我将创建一个进度对话框,然后定期更新它 但这是我在手术结束后偶尔收到的错误 Fatal Exception: java.lang.IllegalArgumentException View=DecorView@1234567[ABC:] not attached to window manager Packag

我创建了一个应用程序,它需要在后台运行一段时间(假设10-15分钟)

我正在异步任务中运行此操作。因此,在这段时间内,用户将屏幕最小化,并像往常一样在手机中使用其他应用程序

启动此操作时,我将创建一个进度对话框,然后定期更新它

但这是我在手术结束后偶尔收到的错误

Fatal Exception: java.lang.IllegalArgumentException
View=DecorView@1234567[ABC:] not attached to window manager PackageName
这是详细的堆栈日志

致命异常:java.lang.IllegalArgumentException 看法=DecorView@1234567[ABC:]未连接到窗口管理器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)
据我所知,此错误是因为Android操作系统想要释放一些内存,因此我的应用程序被关闭,因为用户看不到。但是有什么办法解决这个问题吗?

任何帮助都将不胜感激

编辑:这是我正在使用的代码

 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.
                    }
                });
        }
公共类加载扩展异步任务{
@凌驾
公共作废doInBackground(作废…作废){

对于(int i=0;i有几句话要说:(1)在UiThread/MainThread上已经执行了“onPostExecuted()”方法,因此不需要使用“runUnuithRead()”。(2)如果在异步任务到达最后一个过程时活动被最小化/销毁,则会出现异常。因此,必须使用“View.IsAttachedToWindow()”检查视图是否已附加在执行一些GUI方法之前,如“mProgressDialog.cancel()”(3)您必须创建一个线程或服务来执行一个应该运行/工作几秒钟以上的任务,否则系统可能会随时终止它。

您发生此崩溃是因为您试图在UI位于后台时更新它,因此您的
活动可能会在此时被销毁。顺便说一句,
onPostExecute
运行您的已经在主线程上编写了代码,但是当您向主循环器发送一条单独的消息时,您的逻辑延迟了一点,这也可能会导致问题。此外,主要的问题是,如果用户无论如何都看不到UI,为什么要更新UI

此外,由于您将
AsyncTask
用作内部类,因此任务隐式引用
Activity
对象时,可能会泄漏(尽管是临时泄漏)

发件人:

AsyncTasks最好用于短期操作(几秒钟 如果您需要让线程长时间运行 同时,强烈建议您使用 并发包,如Executor、ThreadPoolExecutor 未来的任务

因此,不要将AsyncTasks用于长时间运行的操作。更好的方法是使用:

  • IntentService
    BroadcastReceiver
    一起与您的
    活动进行通信
    /
    片段
    (在
    API>=26
    中,您应该使用
    JobIntentService
    ,因为
    IntentService
    可能会因后台服务的新限制而行为不当)
  • RxAndroid
    (或者只是
    ExecutorService
    /
    线程
    )以及
    体系结构组件(更具体地说是
    LiveData
    )-这样可以缓存任务的结果,或者在配置更改后仍然有效

  • 我个人最喜欢的是选项2。

    您应该创建一个前台服务来执行该任务,以确保它不会被系统杀死。@答案是Pawel Thans。假设该服务没有被杀死,但Android操作系统有可能杀死该活动吗?请显示相关代码。@Anatolii将很快用cod更新e、 @Anatolii已经用代码更新了问题。你能看一下吗。谢谢你的意见。1)但是很多时候我在
    onPostExecuted()
    上收到一个错误,因此我使用
    runOnUiThread()
    always.3)假设我创建了一个服务来运行该操作,但该活动会被销毁吗?即使该活动完全像Asynctask一样被销毁,该服务或线程也会运行。如果服务上使用了粘性标志,则系统可以自动重新启动该服务,但粘性服务是最新被杀死的服务之一如果系统需要内存,那么kill过程很少发生。谢谢你的帮助。但是@Anatolii似乎解决了这个问题。对此表示抱歉,但他的回答更详细,让我能够理解,并提供了一个完整的解决方案。再次表示歉意。感谢你的回答。如何保存/缓存ArrayList。也有可能吗是否同时运行两个Intent服务?您的回答非常详细,非常有帮助。谢谢again@RajeshK不客气。1)将ArrayList保存在何处?如果要将其从服务发送到活动,则可以使用Intent并将其放入Serializable(putSerializable()方法)中2)可以并行运行多个IntentService。2)您能帮我回答这个问题吗