Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> android線程與線程池-----AsyncTask(一)《android開發藝術與探索》,asynctask線程池

android線程與線程池-----AsyncTask(一)《android開發藝術與探索》,asynctask線程池

編輯:關於android開發

android線程與線程池-----AsyncTask(一)《android開發藝術與探索》,asynctask線程池


線程在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這個方法。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved