一般我们遇到最多的都是让子线程给主线程发送消息,这种方式我就不说了,今天来说说,主线程给子线程发送消息。
1、首先我们在Activity中的onCreate方法中开启一个子线程,然后在子线程中进行Looper和Handler的创建等
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
/**
* 1、创建了Looper对象,然后Looper对象中创建了MessageQueue
* 2、并将当前的Looper对象跟当前的线程(子线程)绑定ThreadLocal
*/
Looper.prepare();
/**
* 1、创建Handler对象,然后从当前线程中获取Looper对象,然后获取到MessageQueue对象
*/
subHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(MainActivity.this,msg.obj.toString(),Toast.LENGTH_LONG).show();
}
};
/**
* 1、从当前线程中找到之前创建的Looper对象,然后找到MessageQueue
* 2、开启死循环,遍历消息池中的消息
* 3、当获取到msg的时候,调用这个msg的handler的dispatchMsg方法,让msg执行起来
*/
Looper.loop();
Log.e("zxj","loop()方法执行完了");
}
}).start();
}
2、然后在点击事件中发送消息
public void onSendClick(View v){
//从消息池中获取一个旧的msg,如果没有,重新创建消息
Message message = subHandler.obtainMessage(1, "我是主线程发送来是消息");
message.sendToTarget();
}
3、问题
以上的写法还是存在一些问题的,其实你在运行起来后,点击按钮发送消息后,当你退出当前Activity后,发现上面定义的log日志,没有执行,这就说明,那个子线程一直未执行完,为啥呢?其实就是因为loop()这个方法,因为这个方法就一个死循环的,所以这个方法一直在循环中,从而导致子线程一直没有执行完,最终会导致内存泄露
4、解决方法
在子线程中拿到创建的Looper对象(Looper.myLooper()),然后在onDestroy中中止loop方法
@Override
protected void onDestroy() {
super.onDestroy();
if(myLooper != null)
myLooper.quit();
}
5、最终代码
public class MainActivity extends AppCompatActivity {
private Handler subHandler;//是在子线程中创建的Handler对象
private Looper myLooper;//子线程中的Looper对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
/**
* 1、创建了Looper对象,然后Looper对象中创建了MessageQueue
* 2、并将当前的Looper对象跟当前的线程(子线程)绑定ThreadLocal
*/
Looper.prepare();
/**
* 1、创建Handler对象,然后从当前线程中获取Looper对象,然后获取到MessageQueue对象
*/
subHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Toast.makeText(MainActivity.this,msg.obj.toString(),Toast.LENGTH_LONG).show();
}
};
//获取当前线程中的Looper对象
myLooper = Looper.myLooper();
/**
* 1、从当前线程中找到之前创建的Looper对象,然后找到MessageQueue
* 2、开启死循环,遍历消息池中的消息
* 3、当获取到msg的时候,调用这个msg的handler的dispatchMsg方法,让msg执行起来
*/
Looper.loop();
Log.e("zxj","loop()方法执行完了");
}
}).start();
}
public void onSendClick(View v){
//从消息池中获取一个旧的msg,如果没有,重新创建消息
Message message = subHandler.obtainMessage(1, "我是主线程发送来是消息");
message.sendToTarget();
}
@Override
protected void onDestroy() {
super.onDestroy();
if(myLooper != null)
myLooper.quit();
}
}