在Activity内部都包含了一个looper对象,它会自动管理looper,处理子线程发来的消息。因此在主线程中向子线程中发送信息时不需要调用looper对象。
如果我们在主线程中调用Looper.prepare()方法会发生什么
在btn01中没有去添加Looper.prepare()方法与btn02进行对比
btn01.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myHandler = new MyHandler();
//获取一个Message对象 等同于去 new 一个Message
Message message = Message.obtain();
message.what =1;
message.obj = "默认的looper";
myHandler.sendMessage(message);
}
});
btn02.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取Looper 准备
Looper.prepare();
//拿到一个Looper对象 来自于 主线程
Looper looper = Looper.myLooper();
myHandler = new MyHandler(looper);
Message mmsg = Message.obtain();
mmsg.what =2;
mmsg.obj = "使用当前线程的Looper";
myHandler.sendMessage(mmsg);
}
});
public class MyHandler extends Handler{
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
tv.setText("what="+msg.what+"-----"+msg.obj.toString());
}
//无参构造
public MyHandler() {
}
//有参构造 Looper
public MyHandler(@NonNull Looper looper) {
super(looper);
}
}
当我们点击btn01时可以正常显示
若我们点击btn02时就会导致系统崩溃,并给我们报一段这样的错,说每个线程只能创建一个Looper。因此可以断定Activity内部都包含了一个looper对象。
那在什么时候会用到Looper呢?当我们从子线程向主线程发送信息时我们可以用到。
public class Main3Activity extends AppCompatActivity {
Button btn;
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
btn = findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.obj = "滴滴";
handler.sendMessage(message);
}
});
//开启一个子线程
new Thread(){
@Override
public void run() {
//获取Looper 准备
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
String string = msg.obj.toString();
Toast.makeText(Main3Activity.this,string,Toast.LENGTH_SHORT).show();
}
};
Looper.loop();
}
}.start();
}
}
对子线程而言,没有任何对象会帮助我们维护Looper,需要我们手动开启
- 这时候需要用到Looper.prepare();Looper.loop();
- 在实际开发中,很少会用到UI主线程向子线程发送消息