當前位置:
首頁 > 最新 > Android非同步處理

Android非同步處理

大家好,我叫王菜鳥,今天給大家分享的內容是Android中非同步的處理。那下面我們就從幾個方面開始介紹Android中的非同步操作。

什麼是同步,什麼是非同步。

為什麼要非同步?

Android中非同步有哪些?對應這些非同步操作的原理是什麼?

如何進行非同步操作?

什麼是同步,什麼是非同步?

同步,非同步可以理解成是形容詞,修飾一次方法的調用,同步方法一旦開始,調用者必須等到方法調用返回後才進行後面的一系列操作。非同步方法調用,則比較類似一次消息的發送,一旦開始就會立即返回,調用者此時不用等待被調用的操作執行完成才繼續執行,而是繼續處理調用者後續的操作。

為什麼要非同步?

我們要清楚為什麼非同步,那就得知道什麼是並行什麼是並發。並行的多個任務是同時執行的,但是對於並發來講這個過程只是不斷交換的過程。怎麼理解這兩個過程,比如說我們在調節婆媳關係的時候,我們一定是跑到媽那裡說媳婦好話,然後屁顛屁顛跑到媳婦那裡說媽也是為了咱們好。跑來跑去這個過程就叫做並發,因為對於這個整體而言你和媽溝通好了,你也和媳婦溝通好了,通過不斷地交替完成了一個結果。那什麼是並行呢?你不太會說話,你就想出來把村長叫來,村長和你媽溝通,你和你媳婦溝通最後結果還是和解婆媳關係。這就叫做並發。

那麼在pc中怎麼理解,如果pc是單核的那就談不上並行,因為沒有村長。只能靠自己和解。那如果pc是多核那就談得上並行,可以叫上村長,如果更多核可以連村長媳婦都叫來都沒問題。

如果把村長媳婦叫來,那可能存在隱患,比如你看上人家村長媳婦了,矛盾更大了,最後體現關係緩和不了,這就叫做死鎖。因為你看上村長媳婦村長看上你媳婦。但是由於道德約束和法律約束,不能互換。但是喜歡就是喜歡永不放棄,這就產生了死鎖。

回歸我們說的為什麼要非同步,放入pc中看,多核可以並行那就省去了你的不少事情,就相當於因為把一半的事情都交給村長了。所以效率會更好。計算機中也一樣多個線程計算效率會更高。所以提高運算效率就是非同步的,目的。

Android中非同步有哪些操作,對應這些操作原理是什麼?

首先我們作為在Android概念區別的的角度而言,Android中核心的可以劃分成

主線程

Binder線程

後台線程 當然如果您要說,主線程Binder線程等在Linux上都是啟動一個線程那您理解的雖然正確,但是沒有在筆者說的這個角度出發看。

主線程

需要明確的是,我們經常說的ActivityThread是主線程,這句話不準確。ActivityThread並沒有繼承Thread類,他只是負責應用進程中一些核心的操作,所以他嚴格意義上不是進程。Zygote把進程fork()出來之後,得做一些Android應用層面的初始化工作,在這個過程中會啟動一套Handler機制我們將這個稱之為主線程,其中的MessageQueue稱之為主消息隊列。其源碼為:

ActivityThread.main()

這也就是我們其實在最開始的線程裡面啟動了一套Handler機制。只不過谷歌把UI操作都讓這個loop處理。所以我們貼切的稱之為主線程。

Binder線程

Binder線程是進行Binder機制通信的線程,也就是Android中的跨進程通信。 Binder線程如果我們是應用開發者很難感知的到Binder線程的存在,因為他是在native層創建的,我們看下源碼,這部分其實作為了解,深入也沒有太大意義,有興趣的同學可以跟隨筆者角度。沒興趣的忽略binder線程繼續向下看哈。

還在Zygote中,當應用層需要啟動一個進程時候(調用Process.start()方法)向Zygote發送socket消息,最後執行到app_main.cpp中的onZygoteInit。

app_main.cpp中的onZygoteInit()

繼續看看如何啟動線程池

追蹤spawnPooledThread方法

這個時候mIsMain=true,通過名稱判斷joinThreadPool加入線程池

也就是在getAndExecuteCommand()這個過程會和Linux底層打交道將BC_ENTER_LOOPER交給底層識別

後台線程

我們在代碼裡面new Thread()這個就叫做後台進程

我們這裡並沒有繼承關係,或者組合關係等,我們只是說常見的一些用到的類,後面我們說這些類分別有什麼作用

Thread

HandlerThread

Executor

AsyncQueryHandler

IntentService

AsyncTask

Thread

針對Thread我們都知道繼承實現run方法,或者把一個Runnable介面給Thread。

我們還知道只要不調用Thread的start()方法,就沒有開啟一個線程,Thread就相當於還是一個普通類。

HandlerThread

HandlerThread是一個集成了Looper,MessageQueue的線程。在其run方法中會調用Looper.prepare()方法,我們看代碼吧。

HandlerThread.java

很顯然我們如果需要做一些事情就放入onLooperPrepared()方法中

AsyncQueryHandler

對於這個,構造中創建了一個HandlerThread自己內部實現了一個Handler叫做WorkerHandler類,這個類封裝了對ContentProvider的一些操作。原理一樣,大概瀏覽下代碼

HandlerThread.java

Excutor

這個只是一個介面。後面和AsyncTask結合那就發揮更大的作用了

IntentService.java

在內部實現了HandlerThread自己實現了Handler叫做ServiceHandler做處理

做的處理是:

原理一樣,都是HandlerThread的應用。

如何進行非同步操作?

就是利用我們上面說的那些進行非同步,只不過我要單獨提出來Handler機制和AsyncTask,後面我會專門詳解,掌握了這兩個基石很多困惑會迎刃而解。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

有必要去上早教課嗎?
真正的個性是堅持做自己

TAG:全球大搜羅 |