Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析

AsyncTask是一种轻量级的异步任务类,可以很方便的在线程池中执行异步任务,并且将进度和结果传递给主线程。其底层由Thread+handler实现。

AsyncTask是一个抽象的泛型类,其类的声明如下:

public abstract class AsyncTask<Params, Progress, Result>

其中三个泛型参数代表的意义如下:

Parmas:参数类型

Progress:异步任务的执行进度类型

Result:异步任务执行完毕后返回结果的类型

在使用AsyncTask执行异步任务需要创建一个类,让这个类继承AsyncTask,并实现相关方法,具体形式如下,在下面代码中实现了几个重要的方法,每个方法代表的意义可以见注释:

/** * Created by liuwei on 18/2/28. */ public class MyAsyncTask extends AsyncTask<String, Integer, String> { /** * 在异步任务执行之前调用 * 执行在主线程中 */ @Override protected void onPreExecute() { super.onPreExecute(); } /** * 执行异步任务 * 执行在线程池中 * @param params * @return */ @Override protected String doInBackground(String... params) { return null; } /** * 当异步任务被取消时执行此方法,此时将不会再调用onPostExecute方法 */ @Override protected void onCancelled() { super.onCancelled(); } /** * 当异步任务执行进度改变时执行此方法 * 执行在主线程中 * @param values */ @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } /** * 当异步任务执行完成后执行此方法 * 执行在主线程中 * @param s */ @Override protected void onPostExecute(String s) { super.onPostExecute(s); } }

要注意的时,需要在doInBackground方法中调用publishProgress()发送任务执行进度,onProgressUpdate才能被回调。

执行AsyncTask是需要在主线程中调用:

new MyAsyncTask().execute();

在使用AsyncTask时有一些限制我们要注意:

AsyncTask类必须在主线程中加载。这是因为在AsyncTask中存在这个一个静态类型的Handler对象成员,在AsyncTask被加载时,该静态类型的Handler对象就会被初始化,所以这就要求了首次访问AsyncTask要发送在主线程中。这一点在Android 4.1及以上版本中已经被系统自动完成。

AsyncTask的对象必须在主线程中创建。

AsyncTask的execute必须在主线程中调用。

不能直接调用onPreExecute()、doInBackground()、onProgressUpdate()、onPostExecute()方法。

一个AsyncTask对象只能调用一次execute,即每个对象只能被执行一次,否则会出异常。

1、使用AsyncTask执行异步任务的小例子

接下类使用AsyncTask,借助循环模拟一个耗时任务的小例子,还是用上面的MyAsyncTask类,并在其相关方法上面添加一些辅助代码,详细代码如下:

public class MyAsyncTask extends AsyncTask<String, Integer, String> { private final static String TAG = MyAsyncTask.class.getSimpleName(); private int taskSize = 10; /** * 在异步任务执行之前调用 * 执行在主线程中 */ @Override protected void onPreExecute() { super.onPreExecute(); Log.i(TAG, "onPreExecute: "); } /** * 执行异步任务 * 执行在线程池中 * @param params * @return */ @Override protected String doInBackground(String... params) { Log.i(TAG, "doInBackground: "); int i; for (i = 0; i < taskSize; i++) { SystemClock.sleep(1000); int progress = (int)((i / (float)taskSize) * 100); publishProgress(progress); if (isCancelled()) { break; } } return "执行结果:" + (i / (float)taskSize) * 100 + "%"; } /** * 当异步任务被取消时执行此方法,此时将不会再调用onPostExecute方法 */ @Override protected void onCancelled() { super.onCancelled(); Log.i(TAG, "onCancelled: "); } @Override protected void onCancelled(String s) { super.onCancelled(s); Log.i(TAG, "onCancelled: result=" + s); } /** * 当异步任务执行进度改变时执行此方法 * 执行在主线程中 * @param values */ @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); Log.i(TAG, "onProgressUpdate: 执行进度:" + values[0] + "%"); } /** * 当异步任务执行完成后执行此方法 * 执行在主线程中 * @param s */ @Override protected void onPostExecute(String s) { super.onPostExecute(s); Log.i(TAG, "onPostExecute: result=" + s); } }

在Activity中调用new MyAsyncTask().execute();执行Log如下:

.../cn.codingblock.thread I/MyAsyncTask: onPreExecute: .../cn.codingblock.thread I/MyAsyncTask: doInBackground: .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:0% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:10% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:20% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:30% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:40% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:50% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:60% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:70% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:80% .../cn.codingblock.thread I/MyAsyncTask: onProgressUpdate: 执行进度:90% .../cn.codingblock.thread I/MyAsyncTask: onPostExecute: result=执行结果:100.0% 2、多个AsyncTask对象在执行异步任务时,默认是串行执行的,也可以通过executeOnExecutor让其并发执行。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyygdg.html