【问题标题】:Handler's `handleMessage` returning thread id of main thread instead that of the worker thread处理程序的 `handleMessage` 返回主线程的线程 id 而不是工作线程的
【发布时间】:2019-09-10 21:29:41
【问题描述】:

我正在尝试了解 Android 中的多线程。我的目标是将数据从主线程发送到工作线程。

我有一个主要活动,其onCreate中包含以下代码-

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ThreadOne threadOne = new ThreadOne();
        threadOne.start();
        threadOneLooper = threadOne.getLooper();

        Message msg = new Message();
        msg.obj = "message.";

        Log.i("id--(threadOneLooper)", String.valueOf(threadOneLooper.getThread().getId()));
        Log.i("id--(Main)", String.valueOf(getMainLooper().getThread().getId()));

        TestHandler mHandler = new TestHandler(threadOneLooper);
        mHandler.handleMessage(msg);
    }

如您所见,我将工作线程的 looper 的引用存储在 threadOneLooper 中,然后记录其关联线程的 id。 同时我也打印了主线程的id。

以下是我的线程的代码 -

public class ThreadOne extends Thread{

    @Override
    public void run() {

        if (Looper.myLooper() == null)
            Looper.prepare();

        Log.i("ThreadOne", "run()");

        // Just making sure all approaches give the same result
        Log.i("Id--Thread id 1", String.valueOf(getLooper().getThread().getId()));
        Log.i("Id--Thread id 2", String.valueOf(getId()));

        Looper.loop();
    }

     Looper getLooper() {
        if (Looper.myLooper() != null)
            return Looper.myLooper();
        else
            return null;
    }

以下是我的处理程序的代码 -

public class TestHandler extends Handler {

    TestHandler(Looper myLooper) {
        super(myLooper);
    }
    public void handleMessage(Message msg) {

        String txt = (String) msg.obj;
        Log.i("Handler", txt);
        Log.i("Id--(Handler)", String.valueOf(getLooper().getThread().getId()));
    }
}

现在,问题是我假设Log.i("Id--(Handler)", String.valueOf(getLooper().getThread().getId())); 语句会记录ThreadOne 的线程ID,因为我们将线程的looper 传递给处理程序。但是,被记录的 id 是主线程的。这是为什么?假设handleMessage() 在主线程上执行是否正确?

【问题讨论】:

  • 请通过Android Looper、Handler和MessageQueue。它会给你答案blog.mindorks.com/…
  • 主要原因是你在主线程中创建了处理程序,为什么这个处理程序总是捕获消息来到主线程
  • @Jasurbek 但我将工作线程的循环器传递给处理程序。在这种情况下,处理程序不应该将自己与工人关联吗?
  • 我还没有答案。但我意识到我的方法不正确 - stackoverflow.com/questions/37671500/… 使用你的方法会给我一个空指针异常。

标签: java android multithreading android-handler android-looper


【解决方案1】:

问题在于ThreadOnegetLooper() 方法。该方法返回与调用该方法的线程关联的myLooper()

为了返回一个与ThreadOne 关联的Looper,我建议使用以下类的实现:

public class ThreadOne extends Thread {
    private Looper mLooper = null;

    @Override
    public void run() {
        Looper.prepare();
        mLooper = Looper.myLooper();

        Looper.loop();
    }

    Looper getLooper() {
        return mLooper;
    }
}

注意!ThreadOneLooper 在运行之前是 null。您不能更早地获得对它的非null 引用。在调用getLooper() 方法之前必须先check if the thread is running

附:您可能需要重新考虑获取ThreadOneLooper 的方法。拥有一个与ThreadOne 关联的Handler 可能就足够了 (see the example of thread)。

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2019-01-26
    • 1970-01-01
    • 2020-02-03
    • 2017-08-21
    相关资源
    最近更新 更多