@作者 : 西野奈留
@博客:http://blog.csdn.net/narunishino
-2017/01/13-更新
-2015/10/8-
2015/10/8
看了很多资料,始终弄不懂Android的多线程是怎么一回事,因为看的资料在主线程(UI线程)里面要么sendMessage(),要么handleMessage()。自己发自己收这么奇怪?
极力按压住无比烦躁的内心(花了超长时间在这上面都看不明白),继续找资料去看,最终耐心战胜了一切,终于让我找到了答案。
在Handler , Looper , Message当中,其实Looper才是主角(之前一直以为是Handler)。
1.一个线程只能有一个Looper,但可以有多个Handler。
2.Handler可以在任意线程发送消息,这些消息会被添加到关联的Looper的MessageQueue上。
//Handler构造函数里面的参数Looper是哪个线程的Looper,那sendMessage就会把消息发给哪个线程。
//下面的例子Looper.myLooper()指的是当前线程,所以sendMessage就会把消息发给当前线程的handleMessage。
Handler handler=new Handler(Looper.myLooper());
handler.sendMessage(message);
/*
ps:(来自于官方文档)Looper的getMainLooper()和myLooper()方法:
static Looper getMainLooper()
Returns the application's main looper, which lives in the main thread of the application.
static Looper myLooper()
Return the Looper object associated with the current thread.
*/
结论:不管在哪个线程都可以发消息或者接收消息,关键要看
Handler()构造函数里面的参数Looper,是哪个线程的Looper,就把消息发给哪个线程。参数为空的话,默认为当前线程。
2017/01/13
更新 ↓↓↓↓↓↓↓↓↓↓↓↓↓
- UI线程会自动创建Looper,子线程默认没有Looper(如有需要,则手动创建)。
- 每个线程最多只有1个Looper。
- 每个Handler都只能属于一个Looper。该Handler属于创建它的构造函数时传入的Looper(getMainLooper()或myLooper()),默认属于当前线程的Looper。
- 当使用Handler的send message(有7个这样的方法)的方法时,会send到它所属的Looper。
// 1.子线程send message到UI线程:
public class MainActivity extends AppCompatActivity {
Handler h = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// 主线程中处理消息
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Message m = new Message();
m.arg1 = 100;
// 子线程中发送消息
h.sendMessage(m);
}
}).start();
}
}
// 2.子线程send message到子线程:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
CustomHandler h3 = new CustomHandler(Looper.myLooper());
Message m = new Message();
m.arg1 = 300;
// 子线程中发送消息
h3.sendMessage(m);
Looper.loop();
}
}).start();
}
class CustomHandler extends Handler {
public CustomHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 子线程中接收消息
}
}
}
// 3.UI线程send message到子线程:
public class MainActivity extends AppCompatActivity {
private CustomHandler h4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
// 子线程中创建Handler
h4 = new CustomHandler(Looper.myLooper());
Looper.loop();
}
}).start();
Message m = new Message();
m.arg1 = 400;
try {
// 主线程不睡一下的话,h4为空,暂时没想到更好的方法,先这样。
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 主线程发消息
h4.sendMessage(m);
}
class CustomHandler extends Handler {
public CustomHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 子线程中接收消息
}
}
}
参考:
《Android开发艺术探索》任玉刚
http://www.jb51.net/article/33514.htm
http://www.bkjia.com/Androidjc/893149.html
-End-