android AsyncTask分析
2016-12-07 22:37
246 查看
android为我们提供了AsyncTask类,它能完成异步任务。 它可以在线程池中进行后台任务,然后把结果返回到主线程中进行UI更新,也可以在任务为完成的情况下返回执行进度,更新UI界面的进度显示。
根据这个类的功能,看起来和上一篇的Handler的使用很类似,没错该类封装了Thread和Handler。官方文档上注释对于长时间的后台任务,不赞同使用该类,推荐使用线程池。
需要注意的点:
AsyncTask的对象必须在主线程创建,execute方法必须在主线程调用。一个AsyncTask对象只能执行一次execute方法。
AsyncTask一般用法:
onPreExecute() 方法: 在异步任务开始前调用。
doInBackground() 方法: 调用该方法执行异步任务,在线程池中运行,处理任务时可以调用publishProgress()方法更新进度,publishProgress()方法会调用onProgressUpdate()方法。
onProgressUpdate() 方法: 在主线程中运行。
onPostExecute() 方法: 在主线程中运行,doInBackground() 方法运行完毕之后,并且中途没有取消,那么就会调用onPostExecute() 方法。
onCancelled() 方法: 如果异步任务被取消,就会回调该方法。
现在分析一下AsyncTask的工作流程代码:
先从构造方法方法开始:
构造方法内会创建2个实例,当前的mFuture封装了mWorker,mWorker的call()会调用doInBackground()方法,并且最后调用postResult()方法。这2个实例比较重要,这里需要注意一下。
接下来我们从execute()方法开始分析:
该方法内部调用了executeOnExecutor()方法:
在上面代码中可以看到,该方法会先调用onPreExecute()方法,之后调用exec.execute()方法,这里的exec是一个SerialExecutor对象,查看该类的代码:
根据上面的代码,之前调用了exec.execute(mFuture),也就是说调用SerialExecutor的execute()方法,在该方法内调用了mFuture的run()方法,run()方法内部调用了mFuture封装的mWorker的call()方法。如果r.run()方法结束,调用scheduleNext()方法,处理下一个异步任务。
查看mWorker的call()方法:
看到这里就非常明简单了,在这里调用了doInBackground()方法,最后调用postResult()方法,查看postResult方法:
异步任务结束后得到的结果会通过getHandler()获得的Handler处理,查看该Handler的代码:
可以发现,该Handler的Looper为主线程中的Looper,所以当前的消息最后到主线程中进行处理,如果当前消息的what为MESSAGE_POST_RESULT,调用finish()方法,同时传入结果,查看AsyncTask的finish()方法:
如果中途没有取消任务,那就会调用onPostExecute()方法,不然调用onCancelled()方法,到这里整个异步任务处理结束。
看一下AsyncTask工作流程:
Created with Raphaël 2.1.0execute()方法onPreExecute()方法SerialExecutor对象的execute(Runnable r)方法调用上面的r的run()方法,也就是mFuture的run(),其内部调用了mWorker的call()方法mWorker.call()方法doInBackground()方法postResult(result)方法Handler发送消息,之后消息进入主线程Handler中调用AsyncTask.finish(result)方法调用onCancelled()或onPostExecute结束
整个AsyncTask工作流程大致就是这样。
根据这个类的功能,看起来和上一篇的Handler的使用很类似,没错该类封装了Thread和Handler。官方文档上注释对于长时间的后台任务,不赞同使用该类,推荐使用线程池。
需要注意的点:
AsyncTask的对象必须在主线程创建,execute方法必须在主线程调用。一个AsyncTask对象只能执行一次execute方法。
AsyncTask一般用法:
//第一个参数表示doInBackground()方法的参数类型 //第二个参数表示onProgressUpdate()方法的参数类型 //第三个参数表示doInBackground()方法返回的参数类型 private class DownloadTask extends AsyncTask<Void, Integer, String> { private String mName; public DownloadTask(String name) { super(); mName = name; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(String s) { super.onPostExecute(s); } @Override protected String doInBackground(Void... params) { return mName; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } }
onPreExecute() 方法: 在异步任务开始前调用。
doInBackground() 方法: 调用该方法执行异步任务,在线程池中运行,处理任务时可以调用publishProgress()方法更新进度,publishProgress()方法会调用onProgressUpdate()方法。
onProgressUpdate() 方法: 在主线程中运行。
onPostExecute() 方法: 在主线程中运行,doInBackground() 方法运行完毕之后,并且中途没有取消,那么就会调用onPostExecute() 方法。
onCancelled() 方法: 如果异步任务被取消,就会回调该方法。
现在分析一下AsyncTask的工作流程代码:
先从构造方法方法开始:
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(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); } } }; }
构造方法内会创建2个实例,当前的mFuture封装了mWorker,mWorker的call()会调用doInBackground()方法,并且最后调用postResult()方法。这2个实例比较重要,这里需要注意一下。
接下来我们从execute()方法开始分析:
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
该方法内部调用了executeOnExecutor()方法:
@MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
在上面代码中可以看到,该方法会先调用onPreExecute()方法,之后调用exec.execute()方法,这里的exec是一个SerialExecutor对象,查看该类的代码:
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
根据上面的代码,之前调用了exec.execute(mFuture),也就是说调用SerialExecutor的execute()方法,在该方法内调用了mFuture的run()方法,run()方法内部调用了mFuture封装的mWorker的call()方法。如果r.run()方法结束,调用scheduleNext()方法,处理下一个异步任务。
查看mWorker的call()方法:
mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } };
看到这里就非常明简单了,在这里调用了doInBackground()方法,最后调用postResult()方法,查看postResult方法:
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
异步任务结束后得到的结果会通过getHandler()获得的Handler处理,查看该Handler的代码:
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }
可以发现,该Handler的Looper为主线程中的Looper,所以当前的消息最后到主线程中进行处理,如果当前消息的what为MESSAGE_POST_RESULT,调用finish()方法,同时传入结果,查看AsyncTask的finish()方法:
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
如果中途没有取消任务,那就会调用onPostExecute()方法,不然调用onCancelled()方法,到这里整个异步任务处理结束。
看一下AsyncTask工作流程:
Created with Raphaël 2.1.0execute()方法onPreExecute()方法SerialExecutor对象的execute(Runnable r)方法调用上面的r的run()方法,也就是mFuture的run(),其内部调用了mWorker的call()方法mWorker.call()方法doInBackground()方法postResult(result)方法Handler发送消息,之后消息进入主线程Handler中调用AsyncTask.finish(result)方法调用onCancelled()或onPostExecute结束
整个AsyncTask工作流程大致就是这样。
相关文章推荐
- Android Studio配置Genymotion 模拟器
- android---- java.lang.NoClassDefFoundError:android.support.v7.widget.TintManager
- Android设计模式读书笔记——工厂方法模式
- Android 圆形图片 CircleImageView(Xfermode方式)
- Android中使用Notification实现宽视图通知栏(Notification示例二)
- 最全面和简单适配屏幕工具AutoLayout的使用教程!
- android volley关于缓存笔记
- Android中使用Notification实现宽视图通知栏(Notification示例二)
- android自定义shape属性
- android的LinearLayout布局
- Android 课堂笔记——shape
- Android版本检测更新
- 在Android中使用并发来提高速度和性能
- Android中.so库的
- Android 渗透测试学习手册 第六章 玩转 SQLite
- android studio 加载.proto不能生成xxxDrpc的问题
- android短视频录制与头像跟随(一)
- [置顶] Android音频和震动的基本实现
- 记录个人Android Studio安装插件列表
- Day12、Android四大组件之Activity