处理程序的 `handleMessage` 返回主线程的线程 ID 而不是工作线程的线程 ID
Handler's `handleMessage` returning thread id of main thread instead that of the worker thread
我正试图在 Android 中掌握多线程的窍门。我的目标是将数据从主线程发送到工作线程。
我有一个主 activity,其 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 是主线程的。这是为什么?假设 handleMessage()
正在主线程上执行是否正确?
问题出在 ThreadOne
的 getLooper()
方法上。与调用该方法的线程关联的方法 returns myLooper()。
为了返回与 ThreadOne
关联的 Looper,我建议 class 的以下实现:
public class ThreadOne extends Thread {
private Looper mLooper = null;
@Override
public void run() {
Looper.prepare();
mLooper = Looper.myLooper();
Looper.loop();
}
Looper getLooper() {
return mLooper;
}
}
注意! ThreadOne
的 Looper 是 null
直到 运行 .您无法更早地获得对它的非 null
引用。在调用 getLooper()
方法之前,您必须 check if the thread is running。
P.S。您可能需要重新考虑获取 ThreadOne
的 Looper 的方法。将 Handler 与 ThreadOne
相关联可能就足够了 (see the example of thread)。
我正试图在 Android 中掌握多线程的窍门。我的目标是将数据从主线程发送到工作线程。
我有一个主 activity,其 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 是主线程的。这是为什么?假设 handleMessage()
正在主线程上执行是否正确?
问题出在 ThreadOne
的 getLooper()
方法上。与调用该方法的线程关联的方法 returns myLooper()。
为了返回与 ThreadOne
关联的 Looper,我建议 class 的以下实现:
public class ThreadOne extends Thread {
private Looper mLooper = null;
@Override
public void run() {
Looper.prepare();
mLooper = Looper.myLooper();
Looper.loop();
}
Looper getLooper() {
return mLooper;
}
}
注意! ThreadOne
的 Looper 是 null
直到 运行 .您无法更早地获得对它的非 null
引用。在调用 getLooper()
方法之前,您必须 check if the thread is running。
P.S。您可能需要重新考虑获取 ThreadOne
的 Looper 的方法。将 Handler 与 ThreadOne
相关联可能就足够了 (see the example of thread)。