上一篇
安卓创建线程线程通信
- 行业动态
- 2025-04-24
- 7
Android创建线程可用Thread或Runnable,通信靠Handler、消息或
安卓线程创建与线程通信详解
线程创建方式
安卓中创建线程的常见方式包括:
继承Thread类
直接创建新线程,每个线程独立运行。class MyThread extends Thread { @Override public void run() { // 线程任务 } } new MyThread().start();
实现Runnable接口
通过Runnable
对象创建线程,灵活性更高。Runnable runnable = new Runnable() { @Override public void run() { // 线程任务 } }; new Thread(runnable).start();
使用HandlerThread
专用于处理消息的线程,自带Looper
。HandlerThread handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); // 启动线程并初始化Looper Handler handler = new Handler(handlerThread.getLooper()); // 获取Handler handler.post(() -> { / 执行任务 / });
使用ExecutorService
基于线程池管理线程,适合并发任务。ExecutorService executor = Executors.newFixedThreadPool(4); executor.execute(() -> { / 任务 / });
线程通信方式
线程间通信需解决数据共享和同步问题,常见方式如下:
通信方式 | 适用场景 | 示例代码 |
---|---|---|
Handler + Message | 同一线程内或跨线程传递消息(需Looper支持) | Handler.sendMessage() /Handle.handleMessage() |
同步工具类 | 多线程协作(如等待任务完成、控制并发) | CountDownLatch 、Semaphore 、Condition |
SharedPreferences | 轻量级数据共享(跨进程需使用MODE_MULTI_PROCESS ) |
SP.edit().putString().apply() |
BroadcastReceiver | 跨进程通信(通过广播传递数据) | 注册BroadcastReceiver 并发送Intent |
LiveData/EventBus | 生命周期安全的数据监听(如MVVM架构中) | LiveData.observe() /EventBus.post() |
典型场景与代码示例
使用Handler通信
// 主线程创建Handler Handler mainHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { // 处理子线程发送的消息 } }; // 子线程发送消息 new Thread(() -> { Message message = Message.obtain(); message.what = 1; mainHandler.sendMessage(message); // 切换到主线程执行 }).start();
使用CountDownLatch同步
CountDownLatch latch = new CountDownLatch(2); // 等待2个线程完成 new Thread(() -> { // 执行任务 latch.countDown(); // 任务完成,计数减1 }).start(); new Thread(() -> { // 执行任务 latch.countDown(); }).start(); latch.await(); // 主线程等待所有子线程完成
注意事项
避免内存泄漏
- Handler需绑定有效的
Looper
,若绑定Activity
的Looper
,需在Activity
销毁时移除回调。 - 使用静态内部类+弱引用(
WeakReference
)避免持有上下文。
- Handler需绑定有效的
线程安全
- 共享数据需加锁或使用原子类(如
AtomicInteger
)。 - 避免在主线程执行耗时操作(如网络请求、文件读写)。
- 共享数据需加锁或使用原子类(如
线程优先级
- 安卓线程默认优先级相同,可通过
Thread.setPriority()
调整,但需谨慎使用。
- 安卓线程默认优先级相同,可通过
相关问题与解答
问题1:Handler导致内存泄漏的原因是什么?如何避免?
解答:
内存泄漏通常因Handler
持有Activity
的强引用,当Activity
销毁时,若Handler
仍存活,会阻止GC回收。
解决方案:
- 使用静态内部类+弱引用:
private static class MyHandler extends Handler { private WeakReference<Activity> mActivity; public MyHandler(Activity activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { Activity activity = mActivity.get(); if (activity != null) { // 处理消息 } } }
- 在
Activity
销毁时移除回调:@Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); }
问题2:为什么推荐使用ExecutorService而不是直接创建线程?
解答:
- 资源复用:线程池复用线程,减少频繁创建/销毁的开销。
- 性能优化:通过
THREAD_POOL_EXECUTOR
等策略控制并发数,避免过多线程竞争资源。 - 任务管理:可统一管理任务队列(如
submit()
提交Callable
任务),便于异常处理和结果回调