Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android:AsyncTask

Android:AsyncTask

編輯:關於Android編程

AsyncTask是異步任務,在不阻塞UI線程的情況下,在後台處理復雜邏輯,並將結果返回到UI線程,現在來分析一下AsyncTask的實現。

先來看看我們常見的使用方法。

先聲明一個類,繼承自AsyncTask。

 

    class MyTask extends AsyncTask{

		@Override
		protected Integer doInBackground(Void... params) {
			// TODO Auto-generated method stub
			return null;
		}
    	
    }
然後使用它

 

 

		MyTask task;
		task = new MyTask();
		task.execute();
具體AsyncTask都做了什麼,一步步看。在AsyncTask內部有兩個很重要的對象

 

 

    private final WorkerRunnable mWorker;
    private final FutureTask mFuture;
先看看WorkerRunnable

 

 

    private static abstract class WorkerRunnable implements Callable {
        Params[] mParams;
    }
WorkerRunnable繼承自Callable,Callable的官方說明是:Callable和Runnable類似,都是可以在另一個線程中執行的,但是二者還是有區別的。

 

1、Callable的接口方法是call,Runnable是run

2、Callable可以帶返回值,Runnable不行

3、Callable可以捕獲異常,Runnable不行

 

public interface Callable {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}
再看看FutureTask,FutureTask是異步計算的結果,繼承關系是 FutureTask -> RunnableFuture->Runnable, Future,FutureTask內部可以判斷任務的執行狀態,並切可以取消任務。

 

FutureTask的構造函數接收一個Callable類型參數,賦值給callable對象

 

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

 

上面的WorkerRunnable被傳入,在FutureTask的run方法中,調用WorkerRunnable的call方法執行,並返回結果。

 

    public void run() {
        ......
        try {
            Callable c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    ......
                }
                if (ran)
                    set(result);
            }
        } finally {
            ......
        }
    }

下面就來看看AsyncTask的初始化

 

 

    public AsyncTask() {
        mWorker = new WorkerRunnable() {
            public Result call() throws Exception {
                ......
            }
        };

        mFuture = new FutureTask(mWorker) {
            @Override
            protected void done() {
                ......
            }
        };
    }
我們看到,之前提到過的兩個對象,在這裡被創建,mFuture實現了done的重載,就是任務完成後,執行此處代碼。當我們執行execute方法是,調用的是下面代碼

 

 

    public final AsyncTask execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

	public final AsyncTask 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;
    }
通過 exec.execute(mFuture); 開始執行任務,execute需要Runnable類型對象,mFuture就是FutureTask類型對象,繼承自Runnable。

 

再看看結果獲得後,返回的動作。

在FutureTask中的run方法中通過 callable 開始執行任務,任務結束後,會執行set方法

 

    public void run() {
        ......
        try {
            Callable c = callable;
            if (c != null && state == NEW) {
                ......
                if (ran)
                    set(result);
            }
        } finally {
            ......
        }
    }
set方法中執行結束任務的方法 finishCompletion,這裡就會調用 done 接口,就通知到了AsyncTask的mFuture的done回調

 

 

    protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }
    private void finishCompletion() {
        // assert state > COMPLETING;
        ......
        done();
        callable = null;        // to reduce footprint
    }
mFuture的done回調中會通過postResultIfNotInvoked調用postResult直接提交結果,那麼對於另一個對象mWorker來說,在call回調中,通過postResult(doInBackground(mParams));去提交結果,所以 doInBackground 是我們必須實現的一個接口函數。

 

postResult中通過內部的一個handler,去通知UI進程,並處理 onPostExecute 及 onProgressUpdate 接口的實現。這樣就完成了任務的整個傳遞。



 


 

 

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