【问题标题】:Blocking Android activity exit until cleanup finishes阻止 Android 活动退出,直到清理完成
【发布时间】:2012-01-03 02:07:17
【问题描述】:

我的活动运行了一个工作线程。退出活动时(例如 onPause()),我正在向该线程发送一条消息,它应该在不久(毫秒)后完成,除非出现问题。 通常,我会在 onPause() 中使用 join(),但在这种情况下,该线程必须使用 UI 线程才能执行其关闭序列(关闭附件文件描述符似乎不适用于任何其他线程) . 所以试图阻塞 UI 线程会导致死锁。我正在寻找一种解决方案,它会以某种方式将应用程序退出推迟到线程退出之后。 可能,如果我可以在这种情况下中止退出,我可以稍后手动调用 finish(),但我不确定是否可以这样做(中止)。

仅仅假设线程最终将完成其清理并退出似乎是一种非常不安全的做法。

【问题讨论】:

    标签: android multithreading android-activity


    【解决方案1】:

    正如你所说,你不能让 UI 线程无限期地等待后台线程停止。

    你可以做以下事情。

    1) 在 onPause() 中中断线程。(如果你想在清理过程中,这不会保留任何信息)

    2)如果你想保留一些信息并执行干净的退出,你可以在 onPause() 中启动一个 Androiod 服务并在那里进行清理。 (在线程中及时检查布尔标志) ex : 一个伪例子

    void run(){
    while(true){
       if(bExit){
        doCleanupWork();
       }
      //Do work
      doWork();
    
      }
    }
    
    void doCleanupWork(){
    startCleanupService();
    }
    
    void onPause(){
    bExit = true;
    }
    

    编辑

    3) 覆盖 Activity 类的 onBackPressed() 使其不会直接退出。启动 AsyncTask 并向用户显示一个对话框,指示在 doInBackground() 中发生清理调用时正在处理。如果您不确定清理可能挂了,你需要重新检查代码,如果需要,在超时后中断线程。

    【讨论】:

    • 在应用程序退出后执行清理不是问题。问题是推迟应用程序退出,直到清理完成。
    • 关于 (3):onBackPressed() 并不是应用退出的唯一情况。任何试图覆盖所有可能的出口路径的尝试,如果可能的话,都是非常不可靠、不便携和不面向未来的。至于 AsyncTask,这是完全没有必要的。通常清理需要几毫秒。我只是想抓住它挂起的任何机会,并确保在完全清理上一次运行之前不会重新启动应用程序。
    【解决方案2】:

    在 UI 线程中声明一个处理程序。当另一个线程完成后,从另一个线程向该处理程序发送一个(空)消息,这将导致 handleMessage 方法在 UI 线程上执行。在 handleMessage 中进行最后的 UI 清理。

    【讨论】:

    • 但这会发生在之后 onPause()onStop() 消息已经被处理,所以应用程序已经退出,不是吗?我想要实现的是将应用程序的退出延迟到线程退出之后,但不会阻塞join() 上的 UI 线程(因为线程清理的一部分涉及在 UI 线程上进行工作,它会导致死锁)。
    • hmmmm -- 我会觉得简单地告诉一个线程从 onStop 关闭......我不认为有任何方法可以“中止”关闭,所以你所能做的就是让线程知道要通过它的关闭程序。您是否担心线程可能无法完全清理?应该给它时间去做它需要做的事情(即,工作线程不会在 UI 线程完成后立即被杀死)。
    • 我担心发现清理问题。我更喜欢 ANR 而不是卡住的线程......另外,我想确保应用程序在干净退出之前不会重新启动。在许多情况下,应用程序会停止/立即重新启动,这可能会导致问题。
    猜你喜欢
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    相关资源
    最近更新 更多