AsyncTask源码分析之二

来源:互联网 发布:起小点淘宝店铺 编辑:程序博客网 时间:2024/05/06 01:45

5,线程切换和管理

5.1,线程切换

AsyncTask中4个方法执行所在的线程如下,是如何切换的呢?

onPreExecute       //主线程,执行任务之前的一些UI操作doInBackground    //子线程,执行任务onProgressUpdate // 任务执行时更新进度信息onPostExecute    // 主线程,任务完成时更新UI

利用内部类InternalHandler,定义如下, InternalHandler代表主线程

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

并且通过getHandler方法可以获取该handler

private static Handler getHandler() {        synchronized (AsyncTask.class) {            if (sHandler == null) {                sHandler = new InternalHandler();            }            return sHandler;        }    }

1, onPreExecute

@MainThread    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;    }

刚开始还没有利用线程池,所以自然在主线程中。

2, doInBackground

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

是线程池中的线程回调,所以doInBackground运行于子线程中。

3, onProgressUpdate/ onPostExecute 

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

InternalHandler定义如下,可以看到,最后通过handler发送消息的方法切换到主线程中执行finish/ onProgressUpdate,并且finish方法中会调用onPostExecute方法,所以onProgressUpdate/ onPostExecute 在主线程中执行。

5.2,线程管理

AsyncTask主要有二个部分:一个是与主线各的交互,另一个就是线程的管理调度。

虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,

其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。

内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当调用了AsyncTask#execute()后,

AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。

0 0