【问题标题】:Android: is it possible to restart Thread's Looper?Android:是否可以重新启动 Thread 的 Looper?
【发布时间】:2013-01-08 19:28:48
【问题描述】:

我有一个简单的问题:如果 (re-loop()) 线程的 Looper 之前退出,是否可以重新启动它。例如,我的线程设计如下:

public class ProvaThread extends Thread implements Runnable{

        public void run(){

            Looper.prepare();
            Handler handler = new Handler(){
                Log.d(TAG, "handle message..");
                @Override
                public void handleMessage(Message msg){

                    getLooper().quit();
                }
            };

            Looper.loop(); //loop 1

            Log.d(TAG, "thread continue (1)...");

            Looper.loop(); //loop 2

            Log.d(TAG, "thread continue (2)...");

        }
    }

我已经尝试过这段代码,但是当我第二次尝试向处理程序发布消息时(handleMessage()在第二个 loop() 之后不调用)。我得出的结论是,当调用getLooper().quit() 时,是否可以调用loop(),但不能处理新消息,否则会引发异常)。对吗?

我应该使用 wait()/notify() 来做这个吗??

【问题讨论】:

  • 如果你不想让looper.quit继续运行,为什么还要调用它呢?您实际上要做什么并不清楚。
  • 您是否尝试大声朗读此代码或向其他人解释?它看起来像这样: 1. 我正在创建消息队列 2. 现在我正在添加消息处理程序,它停止消息队列 3. 启动消息队列 4. 显示日志 5. 启动消息队列 6. 显示日志 这是错误的。
  • 嘿,Log.d(TAG, "handle message..");在任何方法之外?
  • 处理程序中发布的消息来自 UI 线程(消息包含对话响应)。您可以将“线程继续(i)”读作“继续细化(i)”,将“Looper.loop()”读作“在 Ui 线程中发布对话框,使用另一个处理程序,并等待响应”。可能这不是制作这个的正确方法。
  • 我想在 UI 线程(对话框)和工作线程之间执行一种乒乓操作。每个细化步骤都取决于对话框的响应..

标签: android multithreading looper


【解决方案1】:

首先让我解释一下为什么您的示例代码不起作用。 Looper 只处理一个,也只有一个,MessageQueue。当您调用 Looper.prepare() 时会创建此 MessageQueue,并在您调用 Looper.loop() 时处理消息。调用 Looper.quit() 后会发生两件事:

  1. Looper 的 MessageQueue 处于最终终端状态,不会处理任何传入的消息;抛出 RuntimeException。
  2. 它只会在 Looper 尝试检索消息时返回“null”作为消息。

因此,(1) 是 RuntimeException 的原因,(2) 允许您尝试使用 Looper.loop() 重新启动消息检索,但 MessageQueue 仅返回“null”对象。

其次,让我提出一个更好的方法来解决 UI 和工作线程之间的持续通信:

  1. 为 UI 线程创建一个 Handler,称为 mUiHandler。
  2. 创建一个工作线程,例如HandlerThread,并暴露一个Handler,称为mWorkerHandler。

现在,让两个处理程序通过来回发送消息进行通信。为后台任务向 mWorkerHandler 发布消息,并让工作线程在显示或删除对话框时向 mUiHandler 发布消息。

【讨论】:

    【解决方案2】:

    我认为你应该阅读这篇短文http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/。它解释了 Looper 的工作原理以及如何使用它。

    【讨论】:

    • 我的问题是执行一个模式对话框,它会阻塞代码流,直到用户响应!我不想创建一个 Asynctask 链,在 onPostExecute() 中显示对话框,在 doInBackground() 中进行繁重的操作。我只想在一项任务中做到这一点.. 有什么建议吗?
    • 您能解释一下您要实施的案例吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2012-05-09
    • 2012-11-12
    相关资源
    最近更新 更多