当前位置: 首页 > news >正文

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中使用协程时,务必用lifecycleScopeviewModelScope

    • 避免匿名内部类持有外部引用(如非静态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}"
                  }
              }
          }
      }

http://www.dtcms.com/a/122204.html

相关文章:

  • OpenHarmony子系统开发 - 调测工具(二)
  • 柑橘病虫害图像分类数据集OrangeFruitDataset-8600
  • Python: 实现数据可视化分析系统
  • Coze平台 发布AI测试Agent的完整实现方案
  • redis_exporter服务安装并启动
  • STL-list链表
  • mac 苍穹外卖 后端初始 SkyApplication 报错
  • HTTP:一.概述
  • 【Leetcode-Hot100】移动零
  • 净室软件工程:以数学为基石的高可靠性软件开发之道
  • 数学建模--在新能源汽车研发测试中的革命性应用
  • 最小覆盖子串 -- 滑动窗口
  • MMO 架构梳理
  • 分布式ID生成器设计详解
  • 直流有刷电机与H桥驱动
  • JavaScript数据结构-Map的使用
  • Oracle JDBC驱动 ojdbc14:使用指南与版本说明(附资源下载)
  • 建筑兔零基础自学记录69|爬虫Requests-2
  • 开篇 - Unlua+VsCode的智能提示、调试
  • 缓存工具类
  • 嵌入式 C语言 位操作 宏命令
  • spring boot 2.7 集成 Swagger 3.0 API文档工具
  • centos7系统搭建nagios监控
  • 【AI】MCP+cline 实现github官网项目查询
  • .vue文件中组件名称的设置,<script>标签的 name 属性说明
  • JS—浏览器的缓存策略:3分钟精通浏览器缓存策略
  • Vue3中watch监视reactive对象方法详解
  • Java 设计模式:单例模式详解
  • 【算法笔记】并查集详解
  • 蚂蚁 Flink 实时计算编译任务 Koupleless 架构改造