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
原创粉丝点击