Handler
实现,在线程内创建
Handler
并重写
handleMessage()
,外部通过
Handler.sendMessage()
发送数据,若线程未启动消息循环,需先调用
Looper.prepare()
初始化
在Android中,线程间数据传递需要遵循以下原则:
方案 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
Handler | 主线程与工作线程通信 | 简单易用,支持消息封装 | 需手动管理Looper |
BlockingQueue | 多线程顺序处理任务 | 线程安全,支持并发控制 | 需要处理阻塞逻辑 |
LiveData/Flow | 生命周期安全的数据处理 | 自动感知生命周期 | 需要依赖Jetpack库 |
SharedPreference | 轻量级持久化存储 | 持久化存储 | 读写性能较低 |
Parcelable/Serializable | 对象跨进程传输 | 标准接口支持 | 需要实现序列化接口 |
// 定义工作线程 class WorkerThread extends Thread { private Handler mHandler; public void setHandler(Handler handler) { this.mHandler = handler; } @Override public void run() { Looper.prepare(); // 创建消息队列 mHandler = new Handler(){ @Override public void handleMessage(Message msg) { // 处理接收到的数据 String data = msg.getData().getString("key"); Log.d("Worker", "Received: " + data); } }; Looper.loop(); // 启动消息循环 } public void sendData(String data) { Message msg = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("key", data); msg.setData(bundle); mHandler.sendMessage(msg); } }
// 定义共享队列 BlockingQueue<String> queue = new LinkedBlockingQueue<>(); // 生产者线程(主线程) new Thread(() -> { try { queue.put("Hello from Main"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // 消费者线程(工作线程) new Thread(() -> { try { String data = queue.take(); // 阻塞直到有数据 Log.d("Worker", "Received: " + data); } catch (InterruptedException e) { e.printStackTrace(); } }).start();
// 定义LiveData对象 val _data = MutableLiveData<String>() val data: LiveData<String> = _data // 观察者线程(工作线程) data.observe(owner, Observer { value -> Log.d("Worker", "Received: $value") }) // 生产者线程(主线程) _data.postValue("Hello from Main")
A:Android要求UI操作必须在主线程执行,可以通过以下方式实现:
Handler
的post()
方法Activity.runOnUiThread()
View.post()
方法LiveData
/Flow
自动切换线程示例代码:
// 错误用法:直接在子线程更新UI textView.setText("This will crash"); // 正确用法:通过主线程Handler更新 new Handler(Looper.getMainLooper()).post(() -> textView.setText("Safe update"));
A:需要使用线程安全机制保护共享资源:
synchronized
关键字或ReentrantLock
AtomicInteger
等原子操作类ConcurrentHashMap
等并发容器示例代码:
// 使用同步块保护共享资源 Object sharedResource = ...; synchronized(sharedResource){ // 临界区代码,同一时间只有一个线程可以执行 }