Android应用中并行执行任务的最优实现方案咨询
在ViewModel中并行执行耗时任务并返回结果的实现方案
核心思路
借助Android官方推荐的**协程(Coroutines)**实现并行任务,结合ViewModel的viewModelScope管理生命周期,既能保证任务并行执行以节省时间,又能自动避免内存泄漏。三个独立的耗时函数将在不同协程中同时运行,最终通过LiveData把结果传递给Activity展示。
步骤1:迁移耗时函数到ViewModel
把原来Activity中的耗时处理函数移到ViewModel(或独立工具类),确保业务逻辑与UI分离:
// ViewModel内的耗时处理函数示例 private ArrayList<String> processTask1(ArrayList<String> listA, ArrayList<String> listB) { // 模拟耗时操作(实际替换为你的业务逻辑) try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } ArrayList<String> result = new ArrayList<>(); result.addAll(listA); result.addAll(listB); return result; } private ArrayList<Integer> processTask2(ArrayList<Integer> listC, ArrayList<Integer> listD) { try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } ArrayList<Integer> result = new ArrayList<>(); for (int num : listC) { if (num % 2 == 0) result.add(num); } result.addAll(listD); return result; } private ArrayList<Float> processTask3(ArrayList<Float> listE, ArrayList<Float> listF) { try { Thread.sleep(1800); } catch (InterruptedException e) { e.printStackTrace(); } ArrayList<Float> result = new ArrayList<>(); for (float f : listE) { result.add(f * 2); } result.addAll(listF); return result; }
步骤2:在ViewModel中实现并行任务
用async启动三个并行协程,通过awaitAll等待所有任务完成,最终用LiveData暴露结果:
import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import kotlinx.coroutines.Dispatchers; import kotlinx.coroutines.async; import kotlinx.coroutines.launch; public class MyViewModel extends ViewModel { // 封装三个任务结果的数据类 public static class TaskResults { public ArrayList<String> result1; public ArrayList<Integer> result2; public ArrayList<Float> result3; public TaskResults(ArrayList<String> result1, ArrayList<Integer> result2, ArrayList<Float> result3) { this.result1 = result1; this.result2 = result2; this.result3 = result3; } } private final MutableLiveData<TaskResults> taskResultsLiveData = new MutableLiveData<>(); public LiveData<TaskResults> getTaskResultsLiveData() { return taskResultsLiveData; } // 触发并行任务的入口方法,接收Activity传来的所有输入列表 public void startParallelTasks(ArrayList<String> listA, ArrayList<String> listB, ArrayList<Integer> listC, ArrayList<Integer> listD, ArrayList<Float> listE, ArrayList<Float> listF) { // viewModelScope会在ViewModel销毁时自动取消协程,避免内存泄漏 viewModelScope.launch(Dispatchers.Main) { // 在IO线程执行耗时任务,不阻塞主线程 var deferred1 = async(Dispatchers.IO) -> processTask1(listA, listB); var deferred2 = async(Dispatchers.IO) -> processTask2(listC, listD); var deferred3 = async(Dispatchers.IO) -> processTask3(listE, listF); // 等待所有任务完成(三个任务并行执行,总耗时取最长任务的时间) ArrayList<String> res1 = deferred1.await(); ArrayList<Integer> res2 = deferred2.await(); ArrayList<Float> res3 = deferred3.await(); // 主线程更新LiveData,通知Activity刷新UI taskResultsLiveData.postValue(new TaskResults(res1, res2, res3)); } } // 耗时处理函数(同步骤1) private ArrayList<String> processTask1(ArrayList<String> listA, ArrayList<String> listB) { /* ... */ } private ArrayList<Integer> processTask2(ArrayList<Integer> listC, ArrayList<Integer> listD) { /* ... */ } private ArrayList<Float> processTask3(ArrayList<Float> listE, ArrayList<Float> listF) { /* ... */ } }
步骤3:在Activity中观察结果并展示
初始化ViewModel,触发任务后观察LiveData更新UI:
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.lifecycle.ViewModelProvider; public class MainActivity extends AppCompatActivity { private MyViewModel viewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化ViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class); // 准备输入数据(替换为你实际的ArrayList) ArrayList<String> listA = new ArrayList<>(); ArrayList<String> listB = new ArrayList<>(); ArrayList<Integer> listC = new ArrayList<>(); ArrayList<Integer> listD = new ArrayList<>(); ArrayList<Float> listE = new ArrayList<>(); ArrayList<Float> listF = new ArrayList<>(); // 填充数据逻辑... // 启动并行任务 viewModel.startParallelTasks(listA, listB, listC, listD, listE, listF); // 观察结果并更新UI viewModel.getTaskResultsLiveData().observe(this, results -> { // 拿到三个任务的结果,更新你的UI组件(如RecyclerView、TextView等) // 示例:updateTextViews(results.result1, results.result2, results.result3); }); } }
关键注意事项
- 线程调度:始终用
Dispatchers.IO执行耗时任务,Dispatchers.Main用于更新UI,避免ANR。 - 异常处理:可以在
async块中添加try-catch捕获任务异常,比如返回空列表或通过额外的LiveData通知错误状态。 - 数据安全:由于三个任务完全独立,无需处理线程同步;若有共享数据操作,需加锁或用线程安全集合。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

