android,handler实现两个线程通信
16lz
2021-12-04
相关链接:Android HandlerThread 总结
基本概念
android中的Handler对象是两个线程之间通信的桥梁,桥的一端是Handler对象的setXxxMessage()方法(发送msg),另一端是同一个Handler对象的handleMessage(msg)方法(接收msg),两个线程共享一个Handler对象
一个常用的使用场景
Android为了线程安全,并不允许我们在UI线程(主线程)外操作UI,即不允许在子线程中直接操作UI,这时候就需要在子线程中调用Handler对象的setXxxMessage()方法(发送msg),在主线程中调用同一个Handler对象的handleMessage(msg)方法(接收msg),根据msg处理相应的跟新UI逻辑
错误示范:直接在子线程中更新UI
报错信息:Only the original thread that created a view hierarchy can touch its views.
package com.clc.app14;import android.os.Bundle;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import java.util.Timer;import java.util.TimerTask;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //执行Timer的schedule方法时,会新建一个线程 new Timer().schedule(new TimerTask() { int i = 0; @Override public void run() { i ++; //在这个新的线程中操作UI TextView textView = findViewById(R.id.textview); textView.setText(""+i); } },0,1000); }}
利用Handler使子线程间接操作UI(通知主线程跟新UI)
package com.clc.app14;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;import java.util.Timer;import java.util.TimerTask;public class MainActivity extends AppCompatActivity { //系统已经为主线程初始化了一个Looper对象,所以我们直接创建Handler对象 Handler handler = new Handler(){ int i = 0; //重写handleMessage(),接收本对象sendXxx()方法发来的msg对象,并做处理 @Override public void handleMessage(Message msg) { if (msg.what == 1){ i ++; TextView textView = findViewById(R.id.textview); textView.setText(""+i); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Timer().schedule(new TimerTask() { @Override public void run() { //在需要的地方,调用在主线程中实例化的handler对象的sendXxx()方法,向本对象的handleMessage()发送msg //每一次调用sendXxx(),执行一次handleMessage() handler.sendEmptyMessage(1); } },0,1000); }}
另一个demo:自定义一个子线程
package com.clc.app14;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity { Handler handler = new Handler() { //重写handleMessage(),接收本对象sendXxx()方法发来的msg对象,并做处理 //handleMessage()在主线程中执行 //本对象sendXxx()方法的调用与执行,可以在其他线程中 @Override public void handleMessage(Message msg) { if (msg.what == 1){ TextView textView = findViewById(R.id.textview); textView.setText(msg.getData().getString("key")); } } }; //新建一个线程,在这个线程中通知更新UI class Thread1 extends Thread{ @Override public void run() { //创建要发送的msg Message msg = new Message(); msg.what = 1; Bundle bundle = new Bundle(); bundle.putString("key","value"); msg.setData(bundle); //在需要的地方,调用在子线程中实例化的handler对象的sendXxx()方法,向本对象的handleMessage()发送msg //每一次调用sendXxx(),执行一次handleMessage() handler.sendMessage(msg); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //在主线程中启动子线程 Thread1 thread1 = new Thread1(); thread1.start(); }}
更多相关文章
- 浅谈Java中Collections.sort对List排序的两种方法
- 类和 Json对象
- Python list sort方法的具体使用
- python list.sort()根据多个关键字排序的方法实现
- 无废话Android之smartimageview使用、android多线程下载、显式意
- Android的消息机制
- Android(安卓)Launcher 分析
- 通过JavaScript或PHP检测Android设备的代码
- Android(安卓)Binder入门指南之Binder服务的消息循环