Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 多線程Thread,Runnable,Handler,AsyncTask等之間的關系

android 多線程Thread,Runnable,Handler,AsyncTask等之間的關系

編輯:關於Android編程

android 的多線程實際上就是java的多線程。android的UI線程又稱為主線程。

首先是Thread 和 Runnable:

Thread才是一個線程,而Runnable可以理解為一個任務。這個任務只是一個接口。具體的任務執行是在 run()方法執行。

Thread thread = new Thread(Runnable);

那麼就是把一個Runnable任務放到線程裡面。當調用thread.start() 的時候,系統新開一個線程去執行,這個runnable任務是在多線程執行的。是在新開的線程執行的。

但是thread.run() ,這樣子實際上只是在UI線程執行了Runnable 並沒有實現多線程。系統也沒有新開一個線程。

如果直接 new Runnable().run();那麼實際上是直接在UI線程執行了這個任務沒有進行一個多線程的操作。

總結:runnable()只是一個任務的抽象,並不是多線程。Thread.start()。才是新開一個多線程。並且在新開的線程執行Thread你們的run()方法。


來看看android 的多線程通信機制的產物 Handler。

下面這3個方法的hanlder實際上是不涉及多線程的。

post(Runnable) 讓當前線程執行Runnable任務。如果是在主線程調用,那麼就是在UI線程執行Runnable。實際上沒有多線程執行runnable。
postAtTime(Runnable,long) 也是讓當前線程在 時間點long 執行Runnble
postDelayed(Runnable long) 讓當前線程延時 long 後執行Runnable。

這3個方法實際上可以把handler看著是一個任務調度器,而不是一個多線程相關的。


sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long) 發出消息的方法

handleMessage(Message msg)處理消息 這才是android 的hanlder的多線程通信用到的,看下圖

\

可以看到3個線程共用一個消息隊列Message Queue,一個消息循環器LoZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcGVyKNf308Oyu7bP0a27t7bByKHP+8+ittPB0LXEz/vPoimhozwvcD4KPHA+we3N4jK49s/fs8zNqLn9aGFubGRlcrXEc2VuZE1lc3NhZ2W1yLe9t6i3osvNTWVzc2FnZaOsbWVzc2FnZdbQv8nS1LD8uqzK/b7doaO78tXfysfSu9CpYWN0aW9utcSx6rzHJiMyMDU0MDuhozwvcD4KPHA+1vfP37PMtcRoYW5sZGVyzai5/WhhbmRsZU1lc3NhZ2Ww0bD8uqzK/b7dtcjQxc+itcTP+8+iyKGz9sC0oaPV4rj2uf2zzNbQxuTL+8/fs8y1xMr9vt3NqLn9bWVzc2FnZSYjNDM7aGFubGRlcrSrtd21vdb3z9+zzMq1z9a1xLbgz9+zzM2o0MWhozwvcD4KPHA+PGJyPgo8L3A+CjxwPrrDtcTX7rrz1NnLtUFzeW5jVGFzayy/ydLUv6rG9NK7uPa24M/fs8zWtNDQyM7O8aOssqLH0rbgz9+zzLXEyv2+3bSrtd3SssrH09DV4rj2wODX1Ly6zeqzyaGjPC9wPgo8cD7KtbzKyc9Bc3luY1Rhc2sgysfTySB0aHJlYWQgJiM0MzsgaGFuZGxlcrXEt+LXsMq1z9aho8v50tRBc3luY1Rhc2sguPpUaHJlYWQmIzQzO2hhbmRsZXLKtc/Ww7vT0LG+1sq1xLLusfChozwvcD4KPHA+QXN5bmNUYXNrtcS0+sLruPzJ2aOsyrnTw7HIVGhyZWFkJiM0MztoYW5kbGVyvPK1paGjPC9wPgo8cD7W99Kq09AgICAgb25QcmVFeGVjdXRlKCkgOyDKx9a41NrWtNDQtuDP37PMyM7O8daux7C1xNK7uPaz9cq8u6/WtNDQoaPU2lVJz9+zzLX308M8L3A+CjxwPiAgICAgIGRvSW5CYWNrZ3JvdW5kKFBhcmFtcy4uLiBwYXJhbXMpO9XiuPa3vbeoysdBc3luY1Rhc2vQwsb0tq+1xM/fs8zKtc/WtcSho9Ta0MLP37PMtffTwzxicj4KICAgIG9uUG9zdEV4ZWN1dGUoUmVzdWx0IHJlc3VsdCkgOwrV4rj2ysdkb0luQmFja2dyb3VuZCgpt723qNa00NDN6rPJuvOjrLLFtffTw7XEt723qKGjPC9wPgo8cD5yZXN1bHQgvs3Kx2RvSW5CYWNrZ3JvdW5kKCm1xL3hufujrL7NysfTw0hhbmxkZXK1xLe9yr20q7XdtcTK/b7doaPV4rj2t723qNTaVUnP37PMtffTwzxicj4KPGJyPgogICAgcHJvdGVjdGVkIHZvaWQgb25Qcm9ncmVzc1VwZGF0ZShQcm9ncmVzcy4uLiB2YWx1ZXMpO7SmwO3W0Lzkyv2+3aGjZG9JbkJhY2tHcm91bmQoKbe9t6jW0KOsvLTU2tDCv6q1xM/fs8zW0LX308NwdWJsaXNoUHJvZ3Jlc3O3vbeoo6zEx8O0aGFubGRlcr7NsNFwdWJsaXNoUHJvZ3Jlc3O1xCYjMjA1NDA7tKu13bW9VUnP37PM1tChozwvcD4KPHA+sqLH0rDRJiMyMDU0MDu9u7j4b25Qcm9ncmVzc1VwZGF0Zbe9t6i0psDtoaPL+dLUb25Qcm9ncmVzc1VwZGF0ZcrH1NpVSc/fs8y199PDtcShozwvcD4KPHA+PGJyPgo8L3A+CjxwPr+0v7RBc3luY1Rhc2sgtcTUtMLroaM8L3A+CjxwPkFzeW5jVGFza8rHu/nT2s/fs8yz2LXEyrXP1qGjy/nS1M/I0afPsNK7z8LP37PMs9ihozwvcD4KPHA+z9+zzLPYv8nS1NXi0fnA7b3io7rSu9Cpz9+zzLXEvK+6z6GjvNnJ6M7Sw8fV4rj2z9+zzLPYyN3Bv8rHMjAuPC9wPgo8cD7Ex8O00ru49tDCtcTIzs7xwLTBy6OsztLDx8/ryKW/tL+0ztLDx8/fs8yz2LXE09DDu9PQz9+zzLSm09rQ3cPf17TMrKOs09C+zbu90NHIu7rzyMPL+8iltKbA7cjOzvGho7SmwO3N6rPJuvPP37PM0N3D37b4srvKx9axvdO94cr4z9+zzKGjPC9wPgo8cD7Du9PQtKbT2tDdw9/XtMystcTP37PMo6zEx8O0vs3S4s6218UyMLj2z9+zzLa81Nq5pNf3oaPPtc2zsci9z8Omo6zEx8O0vs3Iw9XiuPbIzs7xxcW206GjPC9wPgo8cD48YnI+CjwvcD4KPHA+yOe5+7r2yLvAtMHLMTAwMLj2yM7O8S0txMfDtNPQMjC49r34yOvP37PM1tC0psDtoaPB7c3itcQ5ODC49sjOzvHFxbbToaPV4tH519Oxo9akz7XNs7jf0Ke1xNK7uPbUy9eqoaM8L3A+CjxwPrb4x9Kx3MPisru2z9DCvajP37PMtcS/qs/6oaO/ydLUvqG/ycTctcTJ2b+qxvTP37PMo6yyosfSvfjI68+1zbO1xLX3tsihozwvcD4KPHA+PGJyPgo8L3A+CjxwPsjnufuyu9PDz9+zzLPY1eK49sC0wcsxMDAwuPbIzs7xv6rG9DEwMDC49s/fs8yjrMi7uvO52LHVtfSjrM/CtM7T1tPQyM7O8bXE09bQwr2ooaOho9XiuPa/qs/6w/fP1M/fs8yz2LHcw+LBy6GjPC9wPgo8cD62+MfStbHT0MyrtuC1xM/fs8y68yi4+b7d07K8/imjrM+1zbPDptPaz9+zzLXEtfe2yLW81sLKtbzKyc/P37PMtcTWtNDQ0KfCys/CvbWho8/fs8yz2L/J0tSxo9ak0ru49rrPwO21xM/fs8zK/cG/tvjIw8+1zbPOrLPWtfe2yM/fs8y1xLXNv6rP+qGjPC9wPgo8cD7P37PMs9i7udPQxuTL+7XE0rvQqdbWwOCho87S1eLWu8rHvbK9ss/fs8yz2LXE0ru49srHyrXP1rXEy7zCt6OsvPK1pbXE1K3A7aGjz+vSqs/qz7jBy73iu7m1w9fUvLrJ/cjr0afPsKGjPC9wPgo8cD48YnI+CjwvcD4KPHA+1NphbmRyb2lkz7XNs9bQ1eLW1rr2yLvJzzEwMDC1xMjOzvGyoreiz9bKtdbQy+TIu7K7zKu/ycTcoaOho6GjtavKx7u5ysfNxrz208NBc3luY1Rhc2u1xLD8uqzP37PMs9i1xMq1z9YgyKXX9rbgz9+zzLXEyM7O8aGjPC9wPgo8cD48YnI+CjwvcD4KPHA+t9bO9qO6QXN5bmNUYXNr1LTC6zwvcD4KPHA+PHByZSBjbGFzcz0="brush:java;">public static final Executor SERIAL_EXECUTOR = new SerialExecutor();這是有一個static的線程池對象。這個進程內共用的線程池。(不知道是不是所有android程序都共用這個線程池。。求大神現身。)

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

這樣子線程池執行任務mWorker

mWorker = new WorkerRunnable() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
		//線程池 運行這個任務。並且postResult把結果發出去
                return postResult(doInBackground(mParams));
            }
};

可以看到這個任務執行了doInBackground()方法。這個任務是通過線程池在多線程的環境下執行的。也就是說doInBackground()也是多線程執行的。

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

通過Hanlder + message把結果result傳遞出去。

private static class InternalHandler extends Handler {
        @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;
            }
        }
    } 
private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }



這個hanlder處理接收到的消息。

可以看到調用了finish() 並在finish中調用onPostExecute 讓用戶去使用結果。



最後總結Java的多線程是Thread實現,跟runnable沒有太大關系。

android中因為需要多線程交換數據出現了handler+message+thread實現多線程數據通信。就hanlder本身而言並不是實現多線程。

因為handler+message+thread手寫比較負載,所以android提供AsyncTask去實現多線程,並且擁有多線程數據同步的能力。

AsyncTask的本質就是handler+message+thread(線程池)的實現。因此要是簡單的使用多線程,android中使用asyncTask就足夠了。



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