Android常见的异步线程框架

        当涉及到在 Android 应用程序中处理耗时操作时,如网络请求、数据库访问、IO 操作等,使用异步线程框架是一种常见的方式。异步线程框架允许将这些耗时的操作放在后台线程执行,从而避免阻塞主线程,提高应用程序的响应速度和用户体验。在 Android 开发中,有多种异步线程框架可供选择,如 AsyncTask、Kotlin 协程、Executor 和 RxJava等。这些框架提供了不同的方式来处理异步操作,并具有各自的优势和用途。以下是对 AsyncTask、Kotlin 协程和 Executor 、RxJava异步线程框架的简要介绍:

  1. AsyncTask:是 Android 提供的异步任务处理框架,用于在 UI 线程以外的线程执行耗时操作,然后在 UI 线程更新 UI。它通过封装了线程管理和消息处理机制,简化了在 Android 应用中进行异步任务处理的方式。

  2. Kotlin 协程:是 Kotlin 语言中的一种异步编程框架,用于在非阻塞的方式下处理异步任务。Kotlin 协程通过使用 suspend 关键字来定义挂起函数,可以在代码中使用类似同步代码的方式来处理异步任务,从而避免了回调地狱(Callback Hell)的问题,提供了更简洁、灵活、可读性强的异步编程模型。

  3. Executor:是 Java 标准库提供的线程池框架,用于在多线程环境下管理和调度线程执行任务。Executor 框架通过创建线程池来管理线程的生命周期,并提供了各种不同类型的线程池,如固定大小线程池、缓存线程池、单线程线程池等,以便满足不同的业务需求。

  4. RxJava: 是一款流式编程框架,它基于观察者模式和迭代器模式,提供了一种响应式的编程方式,用于处理异步任务、事件流和数据流等。RxJava 可以帮助开发者简化异步编程的复杂性,提高代码的可读性和可维护性。  

        接下来详细讲讲它们的用法。

一、AsyncTask

        AsyncTask是一个抽象的泛型类,它提供了Params、Progress和Result这三个泛型参数,其中Params表示参数的类型,Progress表示后台任务的执行进度的类型,而Result则表示后台任务的返回结果的类型,如果AsyncTask确实不需要传递具体的参数,三个泛型参数可以用void代替。

AsyncTask的声明如下:

        public abstract class AsyncTask<Params, Progress, Result>

AsyncTask提供了4个核心方法:

        1. onPreExecute(),在主线程中执行,在异步任务执行之前,此方法会被调用,一般用于做一些准备工作。

        2.doInBackground(Params...params),在线程池中执行,此方法用于执行异步任务,params参数表示异步任务的输入参数。在此方法中可以通过publishProgress方法来更新任务的进度,publishProgress方法会调用onProgressUpdate方法。此方法需要返回计算结果给onPostExecute方法。

        3.onProgressUpdate(Progress...values),在主线程中执行,当后台任务的执行进度发生改变时此方法会被调用,其中result参数是后台任务的返回值,即doInBackground的返回值。

        4.onPostExecute(Result result),在主线程中执行,在异步任务执行之后,此方法会被调用,其中result参数是后台任务的返回值,即doInBackground的返回值。

        上面这几个方法,onPreExecute先执行,接着是doInBackgroud,最后才是onPostExecute。除了上述四个方法以外,AsyncTask还提供了onCancelled()方法,它同样在主线程中执行,当异步任务被取消时,onCancelled()方法会被调用,这个时候onPostExecute则不会被调用。下面提供一个典型的示例,如下所示。

import android.os.AsyncTask;

public class MyAsyncTask extends AsyncTask<Void, Integer, String> {

    // 预处理操作
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // 在主线程中执行,可以更新UI,例如显示进度条等
    }

    // 后台任务
    @Override
    protected String doInBackground(Void... voids) {
        // 在后台执行耗时操作,不在主线程中执行
        // 可以执行网络请求、数据库操作等
        return "任务执行结果"; // 返回任务结果
    }

    // 进度更新操作
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        // 在主线程中执行,可以更新UI,例如更新进度条等
    }

    // 任务完成操作
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // 在主线程中执行,可以更新UI,例如显示结果等
    }
}

// 在使用时,可以通过以下方式执行异步任务:
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute(); // 启动异步任务
//取消异步任务:
myAsyncTask.onCancelled();

 二、kotlin协程

        但是,AsyncTask 是一个在 Android 平台上已经过时的类,自从 Android API 级别 30 起已被弃用。推荐使用更现代的异步任务处理方式,如 Kotlin 的协程或者 Java 的 Executor 框架。

以下是使用 Kotlin 协程的示例代码:

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    // 启动一个协程
    GlobalScope.launch {
        println("协程任务开始")
        val result = fetchData() // 模拟耗时操作
        println("协程任务结束,结果:$result")
    }

    println("主线程任务继续执行")

    // 使用协程进行并发任务
    runBlocking {
        val deferred1 = async { fetchData() }
        val deferred2 = async { fetchData() }

        val result1 = deferred1.await()
        val result2 = deferred2.await()

        println("并发任务结果:$result1, $result2")
    }
}

suspend fun fetchData(): String {
    delay(1000) // 模拟耗时操作
    return "数据"
}

        以上代码使用了 Kotlin 协程,通过 launch 函数在全局范围内启动了一个协程,并在其中执行了一个耗时操作。同时,使用 async 函数创建了两个并发的协程任务,并使用 await 函数来等待这两个任务的完成,最终将结果打印出来。

        Kotlin 协程是一种现代的异步任务处理方式,提供了更强大、更灵活、更简洁的异步编程模型,适用于 Android 平台以及其他 JVM 环境。

三、Executor

以下是使用 Java 的 Executor框架的示例代码:

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorExample {

    public static void main(String[] args) {
        // 创建一个单线程 Executor
        Executor executor = Executors.newSingleThreadExecutor();

        // 提交一个任务给 Executor 执行
        executor.execute(() -> {
            System.out.println("任务开始");
            String result = fetchData(); // 模拟耗时操作
            System.out.println("任务结束,结果:" + result);
        });

        System.out.println("主线程任务继续执行");

        // 创建一个线程池 Executor
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // 提交多个任务给 ExecutorService 执行
        Future<String> future1 = executorService.submit(() -> fetchData());
        Future<String> future2 = executorService.submit(() -> fetchData());

        try {
            String result1 = future1.get();
            String result2 = future2.get();

            System.out.println("任务1结果:" + result1);
            System.out.println("任务2结果:" + result2);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 关闭 ExecutorService
        executorService.shutdown();
    }

    public static String fetchData() {
        try {
            Thread.sleep(1000); // 模拟耗时操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "数据";
    }
}

        以上代码使用了 Java 的 Executor 框架,通过 Executors 类创建了一个单线程 Executor 和一个线程池 ExecutorService,并分别提交了任务给 Executor 和 ExecutorService 执行。通过 Future 对象可以获取异步任务的结果,最终将结果打印出来。注意在使用 ExecutorService 后要调用 shutdown() 方法关闭线程池。

四、RxJava

RxJava 的核心概念包括:

  • Observable(被观察者):代表一个数据流的源头,可以发出多个数据项、错误或完成的信号。

  • Observer(观察者):用于订阅 Observable,并对 Observable 发出的数据项、错误和完成信号进行处理。

  • Operator(操作符):用于对 Observable 进行转换、过滤、组合等操作,生成一个新的 Observable。

  • Scheduler(调度器):用于控制 Observable 和 Observer 所运行的线程,例如在主线程或后台线程中执行。

下面是一个简单的 RxJava 示例代码:

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

public class RxJavaExample {

    public static void main(String[] args) {
        // 创建一个 Observable,发出 1、2、3 三个数据项
        Observable<Integer> observable = Observable.just(1, 2, 3);

        // 创建一个 Observer
        Observer<Integer> observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("onSubscribe");
            }

            @Override
            public void onNext(Integer value) {
                System.out.println("onNext: " + value);
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError: " + e.getMessage());
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        };

        // 订阅 Observable,并注册 Observer
        observable.subscribe(observer);
    }
}

        以上代码创建了一个 Observable,发出了三个数据项,然后通过一个 Observer 订阅了这个 Observable,并实现了 Observer 的四个回调方法,分别处理了订阅、数据项、错误和完成信号。当 Observable 发出数据项时,会触发 Observer 的 onNext 方法,将数据项传递给 Observer 进行处理。

        RxJava 还提供了丰富的操作符,例如 map、filter、flatMap、merge 等,可以用于对 Observable 进行转换、过滤、组合等操作,从而实现更复杂的异步编程逻辑。RxJava 在 Android 开发中也得到了广泛应用,例如用于处理网络请求、数据库操作、UI 事件处理等场景,可以大大简化异步编程的代码复杂性。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值