多线程开发---AsyncTask源码解析
来源:互联网 发布:怎么申请软件著作权 编辑:程序博客网 时间:2024/06/06 04:53
在android开发中线程有主副之别,即耗时操作要由子线程操作,然后主线程来更新Ui;handler就充当一个子线程和主线程切换的角色;但是相比于handler,AsyncTask更加轻量级;那么直接开始解析AsyncTask的源码:
1.AsyncTask的使用:
//参一:Params, 参二:Progress, 参三:Result AsyncTask mAsync = new AsyncTask<String,Integer,String>(){ //在开始之前完成初始化等一系列的准备工作 @Override protected void onPreExecute() { super.onPreExecute(); } //在这个方法中处理耗时操作 @Override protected String doInBackground(String... strings) { return null; } //接收处理完的返回值然后开始在UI线程中处理更新Ui的操作 @Override protected void onPostExecute(String s) { super.onPostExecute(s); } //在这里跟新进度条 @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } }.execute(new String[]{"haha"} );
首先来看在new AsyncTask的时候 传入的参数为(Paramas,Progress,Result);在这一步就确定了 耗时操作参数的类型,耗时操作完成之后的返回值类型,进度条progress值的类型
2.execute(Params… params)
首先来看execute源码:
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
看的出来execute的真正实现方法是:executeOnExecutor,ok~接下来来看executeOnExecutor的具体实现:
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; }
在以上源码中,第一步是走的AsyncTask的onPreExecute();相当于数据初始化的准备工作;
之后是mWorker.mParams = params;很明显是个mWorker的mParams属性赋值;ok~ 那么接着来看mWork(WorkerRunnable)这个类的源码实现:
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }
以上代码看不出什么 那么据需看mWorker的具体实例化过程(即是new 该对象的过程):
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Result result = null; try { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked result = doInBackground(mParams); Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { postResult(result); } return result; } };
注意关键代码:result = doInBackground(mParams);在这里mWorker.Params已经赋值完毕;然后params的值赋值给doInBackground的参数;供开发者来实现,以params作为参数来做耗时处理,最后返回result;
接着回到executeOnExecutor方法中 :onPreExecute()—>oWorker.Pramas = pramas;接着来看:exec.execute(mFueture);
那么我们来看mFueture所代表的类实例化的源码:
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); } } };
首先会走FutureTask的构造,将参数mWorker进行初始化的赋值:
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable }
在走完构造之后Future中的run()也会走到,不放来看一下:
```public void run() { if (state != NEW || !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
这里的callable就是穿进来的参数mworker,然后调用mWorker的call方法返回耗时操作(供开发者实现并返回)的返回值,进行set(result)到线程池中(有兴趣要看下线程池的概念,这里先不解释)
这里写代码片
ok~来看下new FutureTask<Result>(mWorker)关键的代码:
postResultIfNotInvoked(get());
先来看get()的实现:
public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s); }@SuppressWarnings("unchecked") private V report(int s) throws ExecutionException { Object x = outcome; if (s == NORMAL) return (V)x; if (s >= CANCELLED) throw new CancellationException(); throw new ExecutionException((Throwable)x); }
可以看出来get()—>reprot(s) 而report返回是(V)x,就是outcome;
然后追溯outcome:
看到outcome在set(Result)中被赋值;
protected void set(V v) { if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; U.putOrderedInt(this, STATE, NORMAL); // final state finishCompletion(); } }
联系前面FutureTask实例化run()中通过set(result)到线程池,get()就是从先前的线程池中取出result;是不是恍然大悟;ok~这样我们就可以将:postResultIfNotInvoked(get());变化为postResultIfNotInvked(result)了;那么接下来看postResultIfNoInvoked的源码:
private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } } private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
很明显是要利用handler将result回归主线程更新ui,顺着猜测往下看,来追溯,handleMessger()的方法:
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; } }
迅速找到刚刚发送msg的what为MESSAGE_POST_RESULT;ok~接下来就简单了 获取result作为参数走到 result.mTask.finish(result.mData[0]);
那么来看finish的源码:
private void finish(Result result) { if (isCancelled()) result = null; // 在主线程中调用更新界面的方法 onPostExecute(result); mStatus = Status.FINISHED; }
显而易见,在finish中调用onPostExecute(result)来更新ui(开发者实现抽象方法onPostExecute(result)来更新ui)
到这里AsyncTask的源码解析就完成了,感谢阅读,期待一起进步,欢迎关注,谢谢~
- 多线程开发---AsyncTask源码解析
- android开发-AsyncTask源码解析
- AsyncTask源码解析
- AsyncTask源码解析
- Android AsyncTask源码解析
- AsyncTask源码解析
- AsyncTask源码解析
- Android AsyncTask 源码解析
- Android AsyncTask 源码解析
- Android AsyncTask 源码解析
- Android AsyncTask 源码解析
- AsyncTask源码解析
- Android AsyncTask 源码解析
- AsyncTask源码解析
- AsyncTask源码解析
- Android AsyncTask 源码解析
- Android:AsyncTask源码解析
- Android AsyncTask源码解析
- JS文件中加载jquery.js(JS文件添加其他JS文件)
- 如何用css3实现卡片3d翻转翻面
- Notepad++ GoLang高亮配置
- JMeter学习-002-JMeter环境配置
- iOS 归档
- 多线程开发---AsyncTask源码解析
- Android Studio / Intellij Tip of the Day
- Webpack配置开发环境 个人土话总结
- 解决mybatis-generator无法生成除insert外的方法的问题
- Word2Vec学习笔记1 初步梳理
- qt project settings被禁用解决方案
- JMeter学习-003-JMeter与LoadRunner的异曲同工
- pandas IO numpy 矩阵
- migrate 和makemigrations的差别