AsyncTask源码分析
来源:互联网 发布:网络打印机安装失败 编辑:程序博客网 时间:2024/06/08 06:31
一. 先了解Java中的FutureTask与Callable
// 创建Callable线程对象Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return "这是Callback Runnable的执行结果"; }};// 创建FutureTask对象, 用于包装Callable, 通过FutureTask.get()可以获取到Callable的返回值FutureTask<String> futureTask = new FutureTask<String>(callable) { @Override protected void done() { super.done(); // 任务执行完成后会回调该方法 Log.e("TAG", "任务执行完毕, FutureTask的done方法在子线程中被回调"); try { Log.e("TAG", get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }};// 开启线程执行任务new Thread(futureTask).start();// 直接在主线程中通过futureTask.get().toString()获取Callable结果, 会阻塞主线程, 直到获取到Call的返回值为止try { Log.e("TAG", "尝试在主线程中获取Callable的Result值"); String callableResult = futureTask.get().toString(); Log.e("TAG", "任务执行完毕, 主线程从阻塞中恢复"); Log.e("TAG", callableResult);} catch (InterruptedException e) { e.printStackTrace();} catch (ExecutionException e) { e.printStackTrace();}
二. AsyncTask源码
1. 通过execute(Params)提交任务, 最终会执行executeOnExecutor()
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params);}/** * 最终会通过这个方法执行AsyncTask任务 */public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { // 通过这个判断说明了, 一个AsyncTask对象只能执行一次任务, 否则会抛出IllegalStateException异常 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成员变量即为CallableRunnable mWorker.mParams = params; // mFuture为FutureTask, 是把mWorker当做实参来实例化的 // exec为sDefaultExecutor, 是一个SerialExecutor, 是一个顺序顺序执行的线程执行者 exec.execute(mFuture); return this;}/*** * 这个线程序列执行者是static的 * 也就是说所有的AsyncTask实例调用的execute()任务任务时都是在这个池中排队执行的 */private static class SerialExecutor implements Executor { // 线程队列 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; // 当一个AsyncTask实例在执行任务时, 其他线程会进入阻塞状态 public synchronized void execute(final Runnable r) { // 开启了一个新线程执行任务 mTasks.offer(new Runnable() { public void run() { try { // 已经在子线程中了, 所以直接调用run()方法 r.run(); } finally { // 当前任务执行完后, 也会执行下一个任务 scheduleNext(); } } }); // 若没有任务, 则会执行下一个任务 if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } }}
2. 当线程执行完成后, 如何回调onPostExecute(Result result)的呢?
由上面的源码可知, 我们执行的任务为一个mFuture(FutureTask的实例), 所以当线程执行完毕后Callable会有一个返回值才对, 我们先看看Callable的返回值是什么
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result>{ Params[] mParams;}/** * AsyncTask的构造函数 */public AsyncTask() { // mWoker的实例化过程, WorkerRunnable这个类implements了Callable mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { // 表明该任务被调用 mTaskInvoked.set(true); Result result = null; try { // 设置线程的优先级 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // 我们可以看到doInBackground是在该Callable线程中回调的 result = doInBackground(mParams); Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { // 将result通过Hanlder切换到主线程去执行 Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); } return result; } }; // mFuture的实例化过程 mFuture = new FutureTask<Result>(mWorker) { // 当Callable执行完成之后会回调done方法 @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); } } };}
3. 在主线程中执行onProgressUpdate() 和 onPostExecute()方法
/** * 这里就是getHanlder获得的Hanlder对象 */private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } @Override public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // 在主线程中处理doInBackground的返回值 result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: // 在主线程中更新doInBackgroud的任务进度 result.mTask.onProgressUpdate(result.mData); break; } }}
阅读全文
0 0
- AsyncTask 源码分析
- AsyncTask源码分析
- Android AsyncTask源码分析
- Android源码分析--AsyncTask
- 源码分析Android AsyncTask
- Android AsyncTask源码分析
- AsyncTask源码分析
- Android-AsyncTask源码分析
- 源码分析--AsyncTask
- AsyncTask源码分析
- AsyncTask源码分析
- AsyncTask源码分析
- AsyncTask源码分析
- Android AsyncTask 源码分析
- AsyncTask源码分析
- AsyncTask源码分析
- AsyncTask源码分析
- AsyncTask源码分析
- Codeforces Round #350 (Div. 2) E 链表
- jsp中使用frame
- Oracle使用sqlplus能连接但是SQL Developer连接失败提示IO错误解决方法
- 匿名内部类的使用
- 《深入理解计算机系统》(原书第三版)家庭作业第三章(3.59)解答
- AsyncTask源码分析
- LintCode 174:Remove Nth Node From End of List
- CSS基础(一)--选择器与权重计算
- mysql面试--数据库优化
- C++初始化列表和构造函数体的区别
- Algorithm Notes (六)Linear List
- ios 上传下载
- Scikit-Learn框架
- Unity协同使用初步总结(StartConroutine_IEnumerator & IEnumeratable)