Android里面开子线程的方法

1. Kotlin协程(官方推荐,最现代化)

适用场景 :几乎全部异步任务(网络请求、数据库、耗时计算等)
优点 :轻量级、自动线程切换、避免回调地狱、完美支持生命周期
示例:

kotlin

复制代码
// 在Activity/Fragment中(需引入lifecycle-ktx)
lifecycleScope.launch {
    // 默认在主线程执行
    val result = withContext(Dispatchers.IO) { // 切换到IO线程
        // 子线程执行耗时操作(如网络请求)
        fetchDataFromNetwork()
    }
    textView.text = result // 自动切回主线程更新UI
}

关键点:

  • Dispatchers.IO:适合磁盘/网络IO操作

  • Dispatchers.Default:适合CPU密集型计算

  • lifecycleScope:自动绑定生命周期,避免内存泄漏


2. Thread + Handler(传统基础方案)

适用场景 :简单后台任务,需要兼容老代码
示例:

java

复制代码
// 开启子线程
new Thread(() -> {
    // 在子线程执行耗时任务
    String result = doHeavyWork();
    
    // 通过Handler切回主线程更新UI
    new Handler(Looper.getMainLooper()).post(() -> {
        textView.setText(result);
    });
}).start();

缺点:需手动管理线程,复杂场景易出错


3. ExecutorService(线程池)

适用场景 :需要控制并发数量的任务(如下载多个文件)
示例:

java

复制代码
// 创建固定大小的线程池(4个线程)
ExecutorService executor = Executors.newFixedThreadPool(4); 

// 提交任务
executor.execute(() -> {
    // 子线程执行任务
    String data = fetchData();
    
    runOnUiThread(() -> { // 切回主线程
        textView.setText(data);
    });
});

// 关闭线程池(通常在onDestroy中)
executor.shutdown();

优点:复用线程资源,避免频繁创建/销毁开销


4. RxJava(响应式编程)

适用场景 :复杂异步任务链(需额外引入库)
示例:

java

复制代码
Observable.fromCallable(() -> {
    // 子线程执行
    return fetchData();
})
.subscribeOn(Schedulers.io()) // 指定子线程执行
.observeOn(AndroidSchedulers.mainThread()) // 切回主线程
.subscribe(data -> {
    textView.setText(data); // 主线程更新UI
});

5. AsyncTask(已废弃,仅了解)

java

复制代码
// ❌ 已废弃!仅用于理解旧代码
private class MyTask extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... voids) {
        return fetchData(); // 子线程执行
    }

    @Override
    protected void onPostExecute(String result) {
        textView.setText(result); // 主线程更新UI
    }
}
// 启动方式
new MyTask().execute();

关键注意事项

  1. UI线程规则:

    • 只有主线程能更新UI,子线程必须通过以下方式切回:

      kotlin

      复制代码
      // Kotlin
      withContext(Dispatchers.Main) { /* 更新UI */ }
      // Java
      runOnUiThread(() -> { /* 更新UI */ });
  2. 内存泄漏:

    • 在Activity/Fragment中使用协程时,务必用lifecycleScope或viewModelScope

    • 避免匿名内部类持有外部引用(如非静态Handler)

  3. 线程选择:

    场景 推荐调度器
    网络请求/文件读写 Dispatchers.IO
    CPU密集型计算 Dispatchers.Default
    数据库(Room) 无需指定,Room自动优化

终极选择建议

  • 新项目 :无脑选 Kotlin协程 (viewModelScope/lifecycleScope)

  • 老项目:

    • 简单任务:Thread + Handler

    • 复杂并发:ExecutorService

    • 已有RxJava:继续使用

    • 协程示例

      复制代码
      // 在ViewModel中
      class MyViewModel : ViewModel() {
          private val _data = MutableLiveData<String>()
          val data: LiveData<String> = _data
      
          fun loadData() {
              viewModelScope.launch {
                  _data.value = "Loading..."
                  try {
                      val result = withContext(Dispatchers.IO) {
                          // 模拟网络请求
                          delay(2000)
                          "加载完成"
                      }
                      _data.value = result
                  } catch (e: Exception) {
                      _data.value = "Error: ${e.message}"
                  }
              }
          }
      }
相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼4 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone4 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen4 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone4 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui