Understanding Android Threading. (Android Performance Patterns Season 5, Ep. 2)

這是Android性能模式的第五季的第二個視頻,如果有人為我為什么會從第五季開始看呢,因為我只是按照官方的順序看下去了,那么下面我們開始來看一下這一期的視頻,視頻地址:

https://www.youtube.com/watch?v=0Z5MZ0jL2BM

Android Performance Patterns.png

接下來我大概會每周翻譯一個視頻的內容。

Pop quiz, hotshot - you're got 48 milliseconds of work to do, but only 16 milliseconds per frame to get it done.

你有一個任務需要 48 ms 完成,但每一幀的繪制最好控制在 16 ms 內完成(這么理解對么)。

What do you do?

這句話不是應該翻譯為你是做什么的么?

My name is Colt McAnils.

視頻中的主講人叫 Colt McAnils。

And while threading on Android can help cure your performance woes, it can also end up creating some huge problems, if you don't understand how it's all working under the hood.

而 Android 中的線程可以幫助我們解決性能問題,如果你不知道線程是如何工作的,那么它一可能會造成一些巨大的問題。

So let's take a few minutes and mask sure we're all on the some page.

所以來讓我們花幾分鐘來認識一下線程(后面那句不是很會翻譯)。

See a thread, by default, does three things.

看一個線程,默認情況下,有三件事情。

線程要做的三件事.png

It starts,It does some works, and this is that work is done, it terminates.

它的開始,它的做的一些工作和做完任務后它的結束。

Now, by itself, that's not too userful.

這句話大概是不是直說單使用線程可能并不是特別有用,就是那種一個單獨任務的那種?

Instead, what you want is a thread that sticks around for a while, so you can feed it packets of work to operate on.

相反,你想讓線程長時間不斷的運行,那就要不斷的給它分配任務。

But to do that. you need a little more scaffolding.

要做的這一點需要一些額外的東西。

First, since threads die when they run out of work, you need to have some sort of loop running on the thread to keep it alive.

首先,線程運行完任務它就 go die 了, 因此我們需要某個循環來保持線程處于活動狀態。

Just make sure to put in an exit condition so you can terminate that loop later.

同時也要保證存在一個退出條件,便于結束后可以退出該循環。

In addition, you'll need some sort of queue that the loop can pull blocks of work from to excute on.

此外,我們還需要一個工作隊列,可以讓循環不斷從中拿到任務執行。

And, of course, you'll need some other thread that creates work pactets and pushes them into the queue of execution.

并且,我們還需要一個另外的線程去創建任務,并且把任務發送到隊列中。

Now if you 've ever tried to write the setup yourself, you know gets a little gnarly to get all that machine reworking incorrectly.

如果你自己編寫一個這種裝置,那么肯定要花一些精力的,大概是這個意思?后面的我不是很會翻譯。

看著像不像Looper.png

Thankfully, thougt, Android has a set of classes to do all that for you.

幸運的是,我們不用自己實現圖中那一套,因為Android已經事先為我們準備好了這一切。

For example, the Looper class will keep the thread alive and pop work off a queue to excute on.

Looger 就是那個保持線程活躍并且從隊列中拿出第一個消息去執行的類。

Looper.png

And rather than always inserting work at the end of that queue, the Handler class gives you the control to push work at the head, the tail, or set a time - based delay that'll keep some work for being processed until that time has passed.

任務并不是總會插入到隊列的末尾,Handler 類 可以讓我們控制把心任務插到哪里的方法,頭部,尾部,或者基于延遲時間,等時間到了再執行該任務。

Handler.png

And don't forget the units of work in Android are explicitly defined as intents or runnables or messages, depending on who's issuing them and who's consuming them.

不過別忘了將 Android 中的任務明確的指定為 intents or runnables or messages,具體還要好看使用場景,誰來發送它們,又是誰來消費它們,所以要看具體的使用場景再決定實用上面三種中的哪一個。

消息隊列.png

And then the combination of all these things together is called a HandlerThead, which lets this look like this(見下面).

HandlerThead 結合了上面那些東西,因為我們在主線程實用 Handler 時,主線程自帶了一個 Looper 而另起的工作線程中想要使用 Handler 需要自己該線程中 Looper 才能運行,HandlerThead 就是自帶 Looper 的一個線程,如下圖:

第一個this指的是這個圖.png
HandlerThead.png

Preffy nifty, huh?

很漂亮是不是?因為已經封裝好了。

So let's look at how you can use this in your application.

讓我們來看看如何讓你使用這些在自己的應用中。

When the user launches you app, Anndroid create its own proces.

當我們運行 App 時,Android 會為我們孵化一個進程,如何孵化呢?通過一個叫Zygote 孵化器。

Alongside with this, them system creates a thread of execution for you application call the Main thead, which, at its core, is just a Handler thread.

除此之外,系統會為 App 創建一個執行線程,叫主線程,它的核心就是Handler thread。

手機啟動創建進程,自帶一個主線程 .png

This Main thread handles processing of events from all over your app, for example, callbacks associated with life cycle information or callbacks from input events, or even events that coming from other application.

主線程會處理 App 中所有事件,例如:與生命周期相關聯的回調函數,來自輸入事件的回調,甚至來自其他應用程序的事件。

And most important is that these callbacks can trigger other work that runs on the thread, too, like make a change to the UI will create work packets that allow the UI to be redrawn.

最重要的是,這些回調會觸發其他在主線程上運行的任務,就像是 UI 改變后將創建一個重繪 UI 的任務。

主線程.png

Basically, this mean that any block of code to your app wants to run has to be pushed into a work queue and then serviced on the Main thread.

基本上,這也意味著 App 想要運行的任何代碼都會被添加到到工作隊列中,然后在主線程上進行服務(我覺得這個服務不是四大組件的服務,只是表達代碼被執行的服務)。

我們的代碼也在主線程中.png

The takeaway here is that with so much work happening on the Main tread, it makes a lot of sense to offload longer work to other threads, as to not disturb the UI system from its rendering duties.

很多工作都發生在主線程,所以講更多這樣的工作放到其他線程上會很有意義,因為這減輕了主線程的負擔,畢竟不要打擾主線程渲染 UI 職責才是正確的做法。

耗時操作放在工作線程,防止UI刷新后掉幀.png

And this is how the entirety of Android's threading model works, lot of packages of work being passed around between threads and worked on as needed.

這就是 Android 線程模型整體的工作原理,許多人物在線程在間傳遞,并根據需需進行工作。

So with all this in mind, some of Android's threading classes make a little bit more sense.

考慮到一切(哪一切?主線程少做事,多負責 UI 么?),Android 中的一些線程類很有意義。

See, each threaded class is instended for a specific type of threading work, so picking the right one of your needs is really important.

Android 中的每個線程類都是針對特定的線程工作而設計的,也就是它們都有自己最合適的使用常見,所以根據你的需求選擇一個正確類是真正重要的事情。

For example, the AsyncTask class is ideal for helping you get work on and off the UI thread in the right way.

例如,AsyncTask 類可以幫助我們以正確的方式處理任務和主線程之間的關系,好像這個上期視頻也提到了。

HandlerThreads are great when you need a dedicated thread for callbacks on land on.

當我們需要一個專門的回調線程時,HandlerThreads 是非常棒的。

And ThreadPools work best when you could break your work up into really small packets and then toss them to bunch of waiting threads.

線程池是當我們有很多需要太后處理的任務時不錯的選擇。

And IntentServices are really ideal for background task or when you need to get intent work off the UI thread.

IntentServices 是一個 Services,非常適用于后臺任務,因為 IntentServices 內部實現原理很簡單,而且會在完成任務后自動結束掉自己。

And like everything else there's not a silver bullet here.

這句話大概意思是說和其他的一樣,這里并沒有最合適的方法。

But knowing which primitive is best for what stiuation, can save you a lot of headaches.

你需要根據自己的需求判斷哪個更適合自己當前使用。

Now, if you ever want more insight into how your app is leveraging threading, make sure you spend some time getting comfortable with Systrace.

現在如果你想要了解如何在 App 中使用線程,你需要花一些時間來學習一下 Systrace,這一個工具。

It's a fancy tool that'll school you on how all that mumbo jumbo is working underneath the hood.

這句話要如何翻譯...

And if you're looking to get school more, make sure you check out the rest of the Android Performance Patterns videos.

人家手動打廣告,歡迎來 YouTube 上觀看 Android Performance Patterns videos。

....以下略,歡迎來Google+ 找他們討論問題...

以上翻譯的肯定會有一些不合適的地方,如果你看到了請指正我,謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,098評論 25 708
  • 我猜,當你看到這個標題時,腦海里冒出了各種累的景象。 其實在寫這篇文章之前我正在洗澡,那時我眼睛都不自主...
    流動的人生閱讀 317評論 0 0
  • 夢想與希望,執著與勇氣,挫折與成長 總有一些東西在瞬間能夠改變人多年的思維與判斷,讓你有一些新的認知。閑來只是想看...
    有一個地方_877e閱讀 252評論 0 0
  • - (void)addTimer { NSLog(@"Retain count A is %ld", CFGetR...
    歐大帥Allen閱讀 696評論 1 1