Asyntask源码分析
来源:互联网 发布:爱普生p50清零软件 编辑:程序博客网 时间:2024/06/14 21:58
Asyntask 是一个抽象类,如果要使用需要继承他
构造方法:
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); } } }; }
以上可以看出构造的时候初始化了两个对象:WorkerRunnable/FutureTask那么这两对象是什么东东呢?先看一下WorkerRunnable
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }这个是AsynTask的内部类私有的 他实现Callable借口 那么这个Callable借口是什么呢? Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。Callable的接口定义如下;public interface Callable { V call() throws Exception; } Callable和Runnable的区别如下:I Callable定义的方法是call,而Runnable定义的方法是run。II Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。III Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。Thread、Runnable、Callable,其中Runnable实现的是void run()方法,Callable实现的是 V call()方法,并且可以返回执行结果,其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。好了了解callable那么再来湫下FutureTask: public class FutureTask<V> implements RunnableFuture<V>他实现了RunnableFuture接口,也就说他既是Runable又是Future 并且实现了里面的所有方法 run cancle isdone等等一个FutureTask 可以用来包装一个 Callable 或是一个runnable对象。因为FurtureTask实现了Runnable方法并且在他的run方法中调用了Callable中的call方法 既然是个Runnable那么AsynTask调用exe方法的时就把他入参,我们看看是不是?我们来一步一步看 public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }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; }
我们看到 exec.execute(mFuture);那么exec是什么呢?他是从AsynTask中的exe方法传入的sDefaultExecutor其实他就是AsynTask中类中的一个静态变量线程池,这个线程池由于是静态的所以所有AynTask对象共同拥有,而且这个线程池是顺序执行的,那么我们也可自定义一个线程使用AynTask另一个方法解决这个问题Executor exec = new ThreadPoolExecutor(15, 200, 10, TimeUnit.SECONDS, new LinkedBlockingQueue()); new DownloadTask().executeOnExecutor(exec);好了言归正传,继续往下看 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); } } }上面是这个线程池的源代码 通过execute把FutrueTask这个对象传入的时候调用FutrueTask的run方法而这个run会调用什么?下面是FutrueTask中的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); }
看到调用了传入的初始化的时候的workCall的call方法并且把结果传给了FutrueTask的set方法再来看一下set方法 protected void set(V v) { if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) { outcome = v; U.putOrderedInt(this, STATE, NORMAL); // final state finishCompletion(); } }调用了FutrueTask的finishCompletion()再来看一下 private void finishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = waiters) != null;) { if (U.compareAndSwapObject(this, WAITERS, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.unpark(t); } WaitNode next = q.next; if (next == null) break; q.next = null; // unlink to help gc q = next; } break; } } done(); callable = null; // to reduce footprint }调用了FutrueTask的done 这个方法被调用说明线程执行完了 而这个方法在AsynTask构造初FutrueTask初始化的时候复写了而在done中调用了 private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } }
看一下方法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; }
从方法中看出发了一个执行结果消息 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; } } }
调用了finish方法 private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }从而调用了onPostExecute(result);整个调用流程就是这样的最后:由于AysnTask里面保存了FutrueTask 对象并且由AysnTask中的线程池执行的,所以AysnTask包装了FutrueTask 的cancel iscancle和get方法0 0
- Asyntask源码分析
- AsynTask源码分析
- Android AsynTask源码分析和优缺点
- AsynTask源码总结
- Android AsynTask 分析
- AsynTask异步任务源代码分析
- AsynTask
- Asyntask
- Android AsynTask 与Thread 或线程池 使用分析
- AsynTask用法
- android-AsynTask
- android AsynTask
- Android AsynTask
- AsynTask 原理
- pullTofresh+AsynTask
- 【AsynTask】android异步任务详解 AsynTask
- android异步任务 AsynTask
- android AsynTask 实现原理
- Remove Duplicates from Sorted List
- 用户常见的问题以及特殊技术问题
- POJ 1129 Channel Allocation(搜索)
- Makefile
- 成绩排序
- Asyntask源码分析
- 10进制转16进制
- 基础篇:2)基于特征设计概念介绍
- 在Linux里设置环境变量的方法(export PATH)
- JAVAScript基础语法介绍
- 嵌入式LINUX环境下视频采集知识(V4L2)
- [NOIP2016] 玩具谜题
- 您已习得新的生产技能,VS查看函数重载
- [openSUSE]How to Install Flash-Plugin for Firefox