之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package cn.lixyz.handlertest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button button; private Handler handler; private int i = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("TTTT", "onClick:" + Thread.currentThread().getName()); Message msg = handler.obtainMessage(); handler.sendMessage(msg); } }); WorkerThread wt = new WorkerThread(); wt.start(); } class WorkerThread extends Thread { @Override public void run() { super.run(); handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("TTTT", "收到了消息对象"); } }; } } }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="30dp" android:text="Send Message" /> </LinearLayout>
上面的问题貌似没什么错误,但运行时却出错
抛出异常:
09-17 04:01:31.655 15854-15869/? E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-120
Process: cn.lixyz.handlertest, PID: 15854
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at cn.lixyz.handlertest.MainActivity$WorkerThread$1.<init>(MainActivity.java:48)
at cn.lixyz.handlertest.MainActivity$WorkerThread.run(MainActivity.java:48)
提示我们没有调用Looper.prepare(),无法创建线程,原因是非主线程中默认是没有创建Looper对象的,需要先调用Looper.prepare()启用Looper。修改一下上面的代码。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
package cn.lixyz.handlertest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button button; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Message msg = handler.obtainMessage(); msg.what = 100; handler.sendMessage(msg); Log.d("TTTT", "sendMessage:" + Thread.currentThread().getName()); } }); WorkerThread wt = new WorkerThread(); wt.start(); } class WorkerThread extends Thread { @Override public void run() { super.run(); Looper.prepare(); handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d("TTTT", "handleMessage:" + Thread.currentThread().getName()); int i = msg.what; Log.d("TTTT", "收到了消息对象:" + i); } }; Looper.loop(); } } }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="30dp" android:text="Send Message" /> </LinearLayout>
运行结果:
09-17 04:29:48.669 28397-28397/cn.lixyz.handlertest D/TTTT﹕ sendMessage:main
09-17 04:29:48.669 28397-28410/cn.lixyz.handlertest D/TTTT﹕ handleMessage:Thread-141
09-17 04:29:48.669 28397-28410/cn.lixyz.handlertest D/TTTT﹕ 收到了消息对象:100
上面代码表示,消息是从MainThread发送的,WorkerThread接收到了消息。
PS:非UI线程默认是没有创建Looper对象的,所以需要主线程向子线程传递消息时,需创建Looper对象并启动循环,子线程才可以循环着从MaessageQueue中取出消息。