【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )

文章目录

一、AsyncTask 参数简介

二、AsyncTask 方法简介

三、AsyncTask 基本用法

四、AsyncTask 构造函数源码解析

五、AsyncTask 构造函数相关源码注释





一、AsyncTask 参数简介


AsyncTask<Void, Void, Void> 泛型类型 :


异步任务开始时 , execute() 方法传入的参数类型 , 也是 doInBackground() 方法传入的参数类型 ;

异步任务执行时 , 进度值类型 , onProgressUpdate() 方法传入的参数类型 ;

异步任务结束时 , 结果类型 , onPostExecute() 方法传入参数类型 , 或 onCancelled() 方法参数 ;





二、AsyncTask 方法简介


AsyncTask 常用方法解析 :


doInBackground() : 核心方法 , 执行异步任务 , 该方法在 子线程 中执行 ;

onPreExecute() : 在 doInBackground() 执行前先执行的方法 , 主线程 中执行 , 可更新 UI 界面 ;

onProgressUpdate() : 调用 publishProgress() 回调的方法 , 主线程 中执行 , 可更新 UI 界面 ;

onPostExecute() : doInBackground() 执行完毕后再执行的方法 , 主线程 中执行 , 可更新 UI 界面 ;





三、AsyncTask 基本用法


AsyncTask 使用注意点 :


UI 线程创建

UI 线程调用执行 execute()

创建后只能执行一次


自定义 AsyncTask 异步任务 :


package kim.hsl.aa;
import android.os.AsyncTask;
/**
 * AsyncTask<String, Integer, Boolean> 泛型解析
 * - 1. 异步任务开始时 , execute 方法传入的参数类型
 * - 2. 异步任务执行时 , 进度值类型
 * - 3. 异步任务结束时 , 结果类型
 */
public class MyAsyncTask extends AsyncTask<String, Integer, Boolean> {
    @Override
    protected void onPreExecute() {
        // doInBackground 之前执行的方法, 一般在该方法中执行初始化操作 ( 主线程, 可以更新 UI )
        super.onPreExecute();
    }
    @Override
    protected Boolean doInBackground(String... strings) {
        // 主要的耗时操作是在该方法中执行的 ( 非主线程, 不能更新 UI )
        return null;
    }
    @Override
    protected void onProgressUpdate(Integer... values) {
        // 在 doInBackground 中调用了 publishProgress 方法, 就会回调该方法
        // 一般情况下是在该方法中执行更新 UI 的操作 ( 主线程, 可以更新 UI )
        super.onProgressUpdate(values);
    }
    @Override
    protected void onPostExecute(Boolean aBoolean) {
        // doInBackground 执行完毕后 , 调用 return 方法后 , 该方法会被调用 ( 主线程, 可以更新 UI )
        super.onPostExecute(aBoolean);
    }
    @Override
    protected void onCancelled() {
        super.onCancelled();
    }
    @Override
    protected void onCancelled(Boolean aBoolean) {
        super.onCancelled(aBoolean);
    }
}



调用异步任务 :


public class MainActivity extends AppCompatActivity {
    private MyAsyncTask mMyAsyncTask;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 创建并执行异步任务
        mMyAsyncTask = new MyAsyncTask();
        mMyAsyncTask.execute();
    }
}





四、AsyncTask 构造函数源码解析


AsyncTask 构造函数作用 : 创建一个新的异步任务 , 该构造函数必须在 UI 主线程调用 ;



构造函数中做了三件事 :


获取 Handler : 该 Handler 是主线程的 Handler ;

创建 WorkerRunnable : WorkerRunnable 是实现了 Callable 接口的抽象类 , 该接口中只定义了一个 call() 函数 ;

创建 FutureTask : FutureTask 是实现了 RunnableFuture 接口的类 , 该接口中定义了一个 run() 方法 ;



Callable 接口简介 : Callable 接口实现类定义一个没有参数的 call 方法 , 该接口与 Runnable 类似 , 两个接口中都被设计为 , 实现类对象的方法可能被另外一个线程执行



Runnable 与 Callable 接口对比 :


Runnable 不能返回结果 , 不能抛出检查过的异常

Callable 是一个任务 , 返回一个结果 , 并抛出异常 ;


WorkerRunnable<Params, Result> 泛型 :


Params 是参数类型 , 也是 AsyncTask 的 doInBackground() 方法的输入参数类型

Result 是返回值类型 , 也是 AsyncTask 的 doInBackground() 方法的执行完毕的返回值类型



RunnableFuture 接口简介 : 该接口继承 Runnable 接口 , Future 接口 ;


在普通的 Thread 方法中 , 调用线程的 start() 方法 , 会执行 Thread 对象中的 run() 方法 , 但是方法执行的结果我们是不知道的 ;


而在 AsyncTask 异步任务中 , 执行 doInBackground() 方法 , 该方法也是在子线程中执行的 , 可以得到该方法执行的结果 , 这个执行结果是靠 Future 接口得到的 ;




在 WorkerRunnable 中的 call() 方法中执行了 doInBackground() 方法 ;


在 FutureTask 中的 done() 方法中 :


执行 postResultIfNotInvoked 方法 : 如果没有被调用 , 那么传递结果 ;

执行 postResult() 方法 : 在该方法中使用主线程 Handler 发送 MESSAGE_POST_RESULT 消息 , 触发 AsyncTask 异步任务的 onPostExecute() 方法





五、AsyncTask 构造函数相关源码注释


public abstract class AsyncTask<Params, Progress, Result> {
  // ...
    /**
     * 创建一个新的异步任务 . 该构造函数必须在 UI 主线程调用 . 
     * @hide 隐藏方法
     */
    public AsyncTask(@Nullable Looper callbackLooper) {
      // 获取 Handler , 用于线程间通信  
      // 获取主线程 Looper 对应的 Handler , 或者创建主线程对应 Handler 
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);
  // 创建工作任务 , 该类是 Callable 接口的子类
  // 实际的 doInBackground() 耗时任务 , 是在该任务中执行的 
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    // 正式执行 doInBackground() 耗时任务 , 在子线程中执行 
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    postResult(result);
                }
                return result;
            }
        };
  // 未来的任务 
        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                try {
                  // 最终会调用该方法 
                    postResultIfNotInvoked(get());
                } catch (InterruptedException e) {
                    android.util.Log.w(LOG_TAG, e);
                } catch (ExecutionException e) {
                    throw new RuntimeException("An error occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
  // 如果没有被调用 , 那么传递结果 
    private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
          // 传递结果 
            postResult(result);
        }
    }
  // 传递结果 , 发送 MESSAGE_POST_RESULT 消息 , 该消息会实际上触发 异步任务 AsyncTask 的 onPostExecute() 方法
    private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }
    // ... 
  /**
  * WorkerRunnable 实现 Callable 接口
  * Callable 是一个任务 , 返回一个结果 , 并抛出异常
  * 实现类定义一个没有参数的 call 方法 
  * 该接口与 Runnable 类似 , 两个接口中都被设计为 : 实现类对象的方法可能被另外一个线程执行
  * Runnable 不能返回结果 , 不能抛出检查过的异常 
  * 
  * Params 是参数类型 , 也是 AsyncTask 的 doInBackground() 方法的输入参数类型
  * Result 是返回值类型 , 也是 AsyncTask 的 doInBackground() 方法的执行完毕的返回值类型 
  */
    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }
  // ... 
}



目录
相关文章
|
Java 数据库 Android开发
【专栏】Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理
【4月更文挑战第27天】本文探讨了Kotlin在Android开发中的多线程优化,包括线程池、协程的使用,任务分解、避免阻塞操作以及资源管理。通过案例分析展示了网络请求、图像处理和数据库操作的优化实践。同时,文章指出并发编程的挑战,如性能评估、调试及兼容性问题,并强调了多线程优化对提升应用性能的重要性。开发者应持续学习和探索新的优化策略,以适应移动应用市场的竞争需求。
516 5
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
446 8
|
Linux Android开发 iOS开发
深入探索Android与iOS的多任务处理机制
在移动操作系统领域,Android和iOS各有千秋,尤其在多任务处理上展现出不同的设计理念和技术实现。本文将深入剖析两大平台在后台管理、资源分配及用户体验方面的策略差异,揭示它们如何平衡性能与电池寿命,为用户带来流畅而高效的操作体验。通过对比分析,我们不仅能够更好地理解各自系统的工作机制,还能为开发者优化应用提供参考。
|
Android开发
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
Android gradle task任务检查各个module之间资源文件冲突.md
|
算法 Linux 调度
深入探索安卓系统的多任务处理机制
【10月更文挑战第21天】 本文旨在为读者提供一个关于Android系统多任务处理机制的全面解析。我们将从Android操作系统的核心架构出发,探讨其如何管理多个应用程序的同时运行,包括进程调度、内存管理和电量优化等方面。通过深入分析,本文揭示了Android在处理多任务时所面临的挑战以及它如何通过创新的解决方案来提高用户体验和设备性能。
697 1
|
缓存 算法 Java
Linux内核新特性年终大盘点-安卓杀后台现象减少的背后功臣MGLRU算法简介
MGLRU是一种新型内存管理算法,它的出现是为了弥补传统LRU(Least Recently Used)和LFU(Least Frequently Used)算法在缓存替换选择上的不足,LRU和LFU的共同缺点就是在做内存页面替换时,只考虑内存页面在最近一段时间内被访问的次数和最后一次的访问时间,但是一个页面的最近访问次数少或者最近一次的访问时间较早,可能仅仅是因为这个内存页面新近才被创建,属于刚刚完成初始化的年代代页面,它的频繁访问往往会出现在初始化之后的一段时间里,那么这时候就把这种年轻代的页面迁移出去
|
Android开发 Kotlin
Android面试题之Kotlin中如何实现串行和并行任务?
本文介绍了 Kotlin 中 `async` 和 `await` 在并发编程中的应用,包括并行与串行任务的处理方法。并通过示例代码展示了如何启动并收集异步任务的结果。
216 0
|
Android开发
40. 【Android教程】AsyncTask:异步任务
40. 【Android教程】AsyncTask:异步任务
396 2
|
XML Java API
30. 【Android教程】吐司提示:Toast 的使用方法
30. 【Android教程】吐司提示:Toast 的使用方法
820 2
|
Android开发
Android Service的两种使用方法
Android Service的两种使用方法
155 2