处理程序的`handleMessage`返回主线程的线程ID,而不是工作线程的ID

时间:2019-04-21 09:51:53

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

我正在尝试在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);
    }

如您所见,我将工作线程的循环程序的引用存储在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,因为我们正在将线程的循环程序传递到处理程序中。但是,正在记录的ID是主线程的ID。这是为什么?假设handleMessage()正在主线程上执行是否正确?

1 个答案:

答案 0 :(得分:1)

问题出在getLooper()的{​​{1}}方法上。该方法返回与调用该方法的线程关联的myLooper()

要返回与ThreadOne关联的 Looper ,我建议使用该类的以下实现:

ThreadOne

注意!public class ThreadOne extends Thread { private Looper mLooper = null; @Override public void run() { Looper.prepare(); mLooper = Looper.myLooper(); Looper.loop(); } Looper getLooper() { return mLooper; } } Looper ThreadOne,直到运行。您之前无法获得非null的引用。您必须先check if the thread is running,然后再调用null方法。

P.S。您可能需要重新考虑使用getLooper() Looper 的方法。与ThreadOne关联 Handler 可能就足够了(see the example of thread)。