AsyncTask源码解读
来源:互联网 发布:waf 源码 编辑:程序博客网 时间:2024/05/22 07:45
虽然说Asynctask很久没用都没用了,现在大部分使用RxJava,Retorfit……但是作为源码分析来讲,我认为还是可以看看的,其实以前看过好多次的,但是从来没有自己整理过,前段时间整理电脑里面的资料,发现了我当时看AsyncTack的流程图,于是,我就对着流程图再来了一遍。
首先是AsyncTask的简单使用:
AsyncTask的使用: AsyncTask task = new AsyncTask<Void, Void, Void>() { @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); //执行完成返回的方法,在UI线程 } @Override protected void onPreExecute() { //一调用就会执行的方法 运行在UI线程 super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { //执行一些耗时的操作 比如连接网络去读取数据,读取大型数据库 运行在主线程中 return null; } }; task.execute();
当调用者执行task.execute()方法之后,该方法去调用executeOnExecutor方法:
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { //做了一些判断,非等待执行状态,第一次进来的状态是默认的Status.PENDING 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.PENDING //所以会执行下面的代码 mStatus = Status.RUNNING; //所以这个代码是一调用就会执行的方法 onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }这样也就解释了AsyncTask 为什么只能执行一次的问题
接着会执行exec.execute(mFuture);而execute是一个抽象方法,传递的参数是一个runnable,
那么这个runnable是哪里来的呢?是在我们new AsyncTask的时候创建的
public AsyncTask() { //这个mWorker就是后面执行run方法所要用到的Callable 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; } }; //FutureTask继承自Runnable 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); } } }; }而这个mFuture是在我们new AsyncTask的时候就会创建的,mFuture的爷爷是Runnable,既然有了runnable,那么肯定会有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 { //这是在执行new AsyncTask中mWorkr的call方法 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); } }
在run()方法中会调用我们在new Asynctask的时候WorkRunnable的call方法
在mWorker的call()方法中然后再去调用
result = doInBackground(mParams);
再次贴出来
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; } };由此可见doInBackground(mParams);就是运行在线程中,不是主线程
然后我们执行拿到result之后在线程中通过handler切换到主线程去
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; }
处理消息:
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; } }finish方法:
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
finish会去判断有没有取消,如果是取消了就会调用onCancelled()方法,否则就是onPostExecute() 执行在主线程中了。
总结:
我们在new AsyncTask的时候,同时会去创建一个WorkerRunnable,他是一个抽象类,实现了Callable,也会去创建一个线程FutureTask,他实现了Runnable接口,当我们
ececute()方法一调用就会去判断状态,如果状态不对就会抛异常,然后会把状态置为Running ,然后执行onPreExecute(), 开一个线程执行 doInBackground(),
doInBackground()执行完毕之后会利用Handler发送消息切换主线程中,然后执行onPostExecute()方法,最后把状态置为FINISHED
最后我们再结合流程图来看看
阅读全文
0 0
- AsyncTask源码解读
- android AsyncTask 源码解读
- AsyncTask源码解读
- AsyncTask异步任务 源码解读
- 面试系列之AsyncTask源码深入解读
- AsyncTask解读
- AsyncTask详细解读
- AsyncTask源码
- AsyncTask源码
- AsyncTask源码
- AsyncTask源码
- 源码解读
- AsyncTask源码解析
- AsyncTask 源码研究
- AsyncTask 源码分析
- AsyncTask源码分析
- Android AsyncTask源码分析
- AsyncTask源码解析
- group by的rollup、cube、grouping、grouping sets 的用法浅析
- 实现字符串中各单词翻转
- javascript中this的使用详解
- 使用LLVM分析函数CFG
- Xcode 4开发第一个iPhone程序 图文实例(下)
- AsyncTask源码解读
- 排序入门--快排
- [thinkPHP5项目实战_06]引入前台页面
- Kotlin Reference (十三) Data Class and Sealed Classes
- ubuntu中 ipv4指令优化以及Invalid argument错误解析
- C语言学习:运算符和表达式
- M
- UITableView的cell的分割线的问题
- Boost.Regex库在linux上的编译安装,使用