AsyncTask源码分析-Android 28

asyncTask主要用于异步处理,是个抽象类,需要实现一个子类。构造的时候有三个参数:

public abstract class AsyncTask<Params, Progress, Result> {

Params 传入的参数,这里是可变的多参形式,你也可以理解为数组的形式。
Progress 耗时操作的进度值,没有的话,可以写Void.
Result 最终的返回结果。

一般多重写三个方法:

	// 后台耗时操作
 	protected abstract Result doInBackground(Params... params);
    //执行任务前的处理,注意是UI线程
    @MainThread
    protected void onPreExecute() {
    }
 	//最终返回的结果,注意是UI线程
    @SuppressWarnings({"UnusedDeclaration"})
    @MainThread
    protected void onPostExecute(Result result) {
    }

第一步;对象的创建

  public AsyncTask(@Nullable Looper callbackLooper) {
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler() // 创建了一个handler
            : new Handler(callbackLooper);
		//创建一个callable接口的实现类,callable是有返回值的线程对象,既然是线程对象,
		//就要看run或者call方法了,能够看到doInBackground方法,这就是执行耗时任务的
		//方法了,而且还返回了一个result对象。
        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 {
                //最后result 给了handler对象。
                    postResult(result);
                }
                return 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);
                }
            }
        };
    }


	// 把请求的对象给handler,getHandler就是该类初始化getMainHandler处理的逻辑。
	   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 Handler getMainHandler() {
	        synchronized (AsyncTask.class) {
	            if (sHandler == null) {
	                sHandler = new InternalHandler(Looper.getMainLooper());
	            }
	            return sHandler;
	        }
	    }

    private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @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;
            }
        }
    }
	//handler更新结果的时候,调用了该方法。当没有取消的时候,就触发了onPostExecute,也就是重写三个方法之一。到此整个流程就结束了。
   private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

到目前为止整个大体流程就结束了,但是好像没有FutureTask什么事,那这个task是干嘛的呢?
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。网上有帖子说FutureTask是获取子线程最终结果,可是这样的解释适合不合理。Callable是一个有结果的线程对象,但是线程一旦启动,大家都知道,不可控制,当然这里是常用的api,比如什么stop之类,这就需要我们创建一些策略来去合理的控制线程对象。因此就有了FutureTask。

FutureTask的继承关系:

public class FutureTask implements RunnableFuture {}

public interface RunnableFuture extends Runnable, Future

Runnable是线程对象。
Future是针对异步计算的结果是否完成及状态的判断。由此可见Future是来管理工作线程的。

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

传入了Callable,该对象就是WorkerRunnable,接下来进入run方法。其中两句话 Callable c = callable; result = c.call(); 获取工作线程的任务结果,最后 set(result);

 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);
        }
    }

   protected void set(V v) {
        if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
            outcome = v;
            U.putOrderedInt(this, STATE, NORMAL); // final state
            finishCompletion();
        }
    }

   /**
     * Removes and signals all waiting threads, invokes done(), and
     * nulls out callable.
     */
    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
    }

finishCompletion很重要,大体翻译就是,移除且标记所有正在等待的线程,调用done方法,且回收callable对象。此处的done就是FutureTask里的done方法了。至此全剧终!

发布了69 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/104335445
28