android线程与线程池-----AsyncTask《android开发艺术与探索》

Posted small_role

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android线程与线程池-----AsyncTask《android开发艺术与探索》相关的知识,希望对你有一定的参考价值。

线程在android是个重要的概念,从用途上讲,线程分为主线程和子线程,主线程负责页面相关,子线程负责耗时操作。

在android中除了Thread本身还有 AsyncTask  IntentService  HandlerThread。

AsyncTask

    public abstract class AsyncTask<Params, Progress, Result>  

1 Params 参数类型
2 Progress 执行进度类型
3 Result 返回数据类型

不需要参数可以用Void代替

它提供了4个核心方法:

    //异步任务执行之前调用,一般用来执行一些准备操作  
           @Override  
           protected void onPreExecute() {  
               super.onPreExecute();  
           }  
           //在线程池调用, 用于执行异步任务  
           @Override  
           protected String doInBackground(String... params) {  
               return null;  
           }  
           //异步任务执行之后会调用  
           @Override  
           protected void onPostExecute(String result) {  
               super.onPostExecute(result);  
           }  
           //主线程中执行,后台任务执行进度发生改变调用  
           @Override  
           protected void onProgressUpdate(Void... values) {  
               super.onProgressUpdate(values);  
        }  

    

注意:

1 AsyncTask类必须在主线程中加载

2 AsyncTask的对象必须在主线程创建

3 execute必须在UI线程调用

4 一个AsyncTask的对象只能执行一次,即只调用一次execute方法


工作原理:

    public final AsyncTask<Params, Progress, Result> execute(Params... params) {  
            return executeOnExecutor(sDefaultExecutor, params);  
        }  
    execute 方法会调用 executeOnExecutor 方法;看一下 executeOnExecutor 方法:  
     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;  
        }  

可以看出封装了一个线程池,接着找我发现了

    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;  
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();  
      
    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();  
                }  
            }  

从SerialExecutor 看出AsyncTask是排队执行的过程。

系统首先会把AsyncTask的参数Params 封装为FutureTask对象,接着会把FutureTask交给SerialExecutor的execute处理,
execute方法把FutureTask交给mTasks任务队列中,如果这时没有AsyncTask任务,SerialExecutor会 scheduleNext()来执行下一个任务。当一个任务执行完以后,SerialExecutor才会执行其他任务,可以看出AsyncTask是串 行的。


AsyncTask构造函数有这样一段代码:

    mWorker = new WorkerRunnable<Params, Result>() {  
                public Result call() throws Exception {  
                    mTaskInvoked.set(true);  
      
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
                    //noinspection unchecked  
                    return postResult(doInBackground(mParams));  
                }  
            };  

再看FutureTask的run方法:

派生到我的代码片

    public void run() {  
            if (state != NEW ||  
                !UNSAFE.compareAndSwapObject(this, runnerOffset,  
                                             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);  
            }  
        }  

发现FutureTask的run方法是执行了mWorker的call的,所以call也会在线程池中执行。


mWorker的call中将mTaskInvoked.set(true);表示当前任务已经调用然后执行AsyncTask的doInBackground方法接着将
返回值传给postResult方法;

    private Result postResult(Result result) {  
          @SuppressWarnings("unchecked")  
          Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,  
                  new AsyncTaskResult<Result>(this, result));  
          message.sendToTarget();  
          return result;  
      }  

可以看出postResult通过一个Handler发送一个MESSAGE_POST_RESULT消息

    private static Handler getHandler() {  
            synchronized (AsyncTask.class) {  
                if (sHandler == null) {  
                    sHandler = new InternalHandler();  
                }  
                return sHandler;  
            }  
        }  
      
      
        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;  
                }  
            }  
        }  

当这个Handler收到MESSAGE_POST_RESULT消息之后,会调用finish方法了

    private void finish(Result result) {  
            if (isCancelled()) {  
                onCancelled(result);  
            } else {  
                onPostExecute(result);  
            }  
            mStatus = Status.FINISHED;  
        }  

如果取消执行就 onCancelled 了,否则就调用onPostExecute这个方法。

 

以上是关于android线程与线程池-----AsyncTask《android开发艺术与探索》的主要内容,如果未能解决你的问题,请参考以下文章

android线程与线程池-----AsyncTask《android开发艺术与探索》

Android-线程池

Android-线程池

Android中的线程池

Android线程池的使用

Android(java)学习笔记267:Android线程池