Android线程AsyncTask源码分析

(1) 用例

class DownLoadAsyncTask extends AsyncTask<String, Integer, String>    
{    
    FullscreenActivity activity;    
    TextView textView;  
    ProgressBar bar;  
  
    public DownLoadAsyncTask (FullscreenActivity activity, TextView textView, ProgressBar bar ) {  
        this.activity = activity;  
        this.textView = textView;  
        this.bar = bar;  
    }  
    //DownLoadAsyncTask 被后台线程执行后,被UI线程被调用,一般用于初始化界面控件,如进度条    
    @Override   
    protected void onPreExecute() {    
        // TODO Auto-generated method stub    
        super.onPreExecute();    
    }    
  
    //doInBackground执行完后由UI线程调用,用于更新界面操作 ,主线程执行   
    @Override   
    protected void onPostExecute(String result) {    
        // TODO Auto-generated method stub  
        //textView.setText(result);    
        super.onPostExecute(result);    
    }    
  
    //在PreExcute执行后被启动AysncTask的后台线程调用,将结果返回给UI线程 ,线程池中执行   
    @Override   
    protected String doInBackground(String... params) {    
        // TODO Auto-generated method stub    
        bar.setMax(300);  
        int i = 30;  
        while(true)  
        {  
            publishProgress((int)i);  
            if(i == 0 ) break;  
            try {  
                Thread.sleep(1000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
            i--;     
        }  
        return null;    
    }  

   //主线程执行
    @Override  
    protected void onProgressUpdate(Integer... values) {  
        // TODO Auto-generated method stub  
        bar.setProgress(values[0]*10);    
        textView.setText("" + values[0] + " s");    
          
        super.onProgressUpdate(values);  
    }    
      
         
}   

//主线程执行

new DownLoadFilesTask(FullscreenActivity.this, textView, bar).execute("");  


(2) 源码分析

AsyncTask封装了线程池和handler,通过AsynTask可以更方便的执行后台任务以及在主线程访问UI。用法new DownLoadFilesTask().execute(params);  

public abstract class AsyncTask<Params, Progress, Result>
Params代表doInBackground中传入的参数类型,Progress代表onProgressUpdate中传入的参数类型,Result是doInBackground返回的参数类型。

/**
* @param params The parameters of the task.
*/ 
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

execute方法执行了executeOnExecutor方法,

    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

从executeOnExecutor方法可以看出,AsyncTask默认执行了一个串行线程池sDefaultExecutor 

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

串行线程池用来依次取出任务。串行线程池用ArrayDeque(队列)来实现任务按顺序插入取出。最终执行任务还是由线程池THREAD_POOL_EXECUTOR来执行

 public final AsyncTask<Params, Progress, Result> executeOnExeconPreExecuteutor(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;
    }

再来看看executeOnExecutor方法,执行了onPreExecute方法,这个方法是空实现,运行在主线程中。然后把params给mWorker.mParams。

mWorker的类型如下,

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }
  然后执行串行线程池sDefaultExecutor 即exec.execute(mFuture);

mFuture的类型如下

    private final FutureTask<Result> mFuture;
mWorker和mFuture都是在AsyncTask构造函数中实例化的。mWorker传入mFuture中,然后mFuture传入串行池的execute方法中,由串行线程池对mFuture进行增删操作,最后由THREAD_POOL_EXECUTOR执行

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

        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 occured while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
mWorker 的方法call中调用了postResult(doInBackground(mParams));方法,这里调用了doInBackground方法,可以看出doInBackground方法是在THREAD_POOL_EXECUTOR线程中执行的。

    protected abstract Result doInBackground(Params... params);
doInBackground是一个抽象类,返回泛型类Result

private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }
因为postResult方法是在线程中执行的,这里postResult中用handler向主线程发送了一个消息。
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;
            }
        }
    }
handleMessage中调用了AsynTask的finish和onProgressUpdate方法,因为这里的looper是主线程looper,

 public InternalHandler() {
            super(Looper.getMainLooper());
        }

handleMessage是在looper所在线程执行,所以finish和onProgressUpdate方法都在主线程执行。

protected void onProgressUpdate(Progress... values) {
    }
显然onProgressUpdate在主线程中执行

private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }
finish方法中调用了onPostExecute,显然onPostExecute也是在主线程中执行
protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

从publishProgress源码可看出,publishProgress想handler发送了一个消息,从而调起了onProgressUpdate方法


(3) 总结


1.AsyncTask是抽象类,有三个泛型类。public abstract class AsyncTask<Params, Progress, Result>
Params代表doInBackground中传入的参数类型,Progress代表onProgressUpdate中传入的参数类型,Result是doInBackground返回的参数类型。


2.AsyncTask有四个核心方法

onPreExecute(),在主线程执行

doInBackground(params),在线程池THREAD_POOL_EXECUTOR执行,返回值result

onProgressUpdate(progress),在主线程执行

onPostExecute(result),在主线程执行


执行顺序:onPreExecute->doInBackground->onPostExecute

onProgressUpdate(progress),可在线程池调用,用于刷新UI,实际发消息从而调起onProgressUpdate


3.XXXAsynTask对象必须在主线程创建             new XXXAsynTask().execute(params);必须在主线程执行          

原因:AsynTask中handler是静态类,所以XXXAsynTask对象创建的时候会创建一个handler对象,并且处理消息的looper是主线程looper,如果要在这里处理UI,就必须在主线程创建


4.AsynTask(用了两个线程池,串行线程池用于任务的有序增删,THREAD_POOL_EXECUTOR线程池用于执行任务


5. new XXXAsynTask(name1).execute(params);

new XXXAsynTask(name2).execute(params);

......

被调用多次是在同一个线程池(线程池是静态线程池)串行执行,如果要并行执行请调用executeOnExecutor(Executor exec,Params... params)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值