實戰技巧:Android異步指南

jopen 9年前發布 | 28K 次閱讀 Android Android開發 移動開發

異步向來都是提高性能的必要手段,當然也是引發問題的常見根源。Android之中更是如 此,主線程事關應用的流暢程度,所以把更多能放在工作線程中事,放到工作線程中去,是提升App性能之必經之路。Android中使用線程有多種方式,我 們該如何選擇,以及在使用過程中要注意哪些問題,今天就來探討一下。

Bitmap處理

在Android中顯示圖片,Bitmap是必須要學會的。Bitmap是Android中抽象出來代表圖片的類,把圖片文件或者數據轉化成Bitmap進而再放置到視圖系統中顯示。Bitmap的處理也常常會引發OOM問題。

關于Bitmap的處理,遵守二個原則,就是按需解析和及時釋放。現在的圖片文件都很大,但很多時候我們需要展示的區域(目標View的大小)卻不是很大,這個時候就需要在解析的時候,適當的降低幀率,以減小所需要申請的內存。及時釋放時也需要注意,要確定不用了,再釋放,如果有View仍在顯示時,在另外的地方把Bitmap釋放了,那會引發異常的。

對于Bitmap的使用,官方文檔有著比較詳細的教程。現在的Android文檔是很齊全的,相比較2010年代時2.0和2.1時多了很多最佳實踐,所以不要浪費。

除內存外,Bitmap的處理也是比較耗時的,因為它經常涉及IO,以及壓縮和處理,即使不耗時,因為它跟UI沒關系,所以也是可以放在工作線程中去做的。Android中記住一個準則就是主線程做的事情越少越好,越少你的應用就越流暢。至于如何具體的去做也建議參考官方教程

異步的方式

在Android中異步實現的方式非常多:

  • Thread
  • AsyncTask
  • Executors
  • Handler, Looper

各種方式的使用方法參閱相關文檔或者查閱網上漿料就可以了。這里主要說一下區別和適用的場景:

Thread

這是Java的簡單粗暴的方式,優點就是簡單,方便。對于某些簡單的,一次性的,不需要與主線程通信和操作UI,不是很頻繁(一次啟動執行一次),的費時操作,直接使用Thread方式還是相當方便的。

AsyncTask

這是Android中專門針對平臺本身的特性而封裝的一個類,它的優勢在于與主線程通信方便,能非常方便的操作UI。所以使用AsyncTask的理由就是當你需要在異步操作完成時直接操作UI時,除此外,你不應該使用它。

使用AsyncTask時,最好使用AsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);以免任務不能及時獲得執行,詳細原因可以看這篇文章

Executors

當有大量的任務,或者重復性的任務需要執行時,就要使用線程池來復用和管理線程。

Handler與Looper

這是Android事件循環的基礎類,也是AsyncTask的實現方式,是線程間通信的利器。所以如果你有復雜的線程通信(通常是工作線程和主線程之間),可以使用這二個類來自行進行定義。

其他的高級工具

對于多線程,已經有足夠的工具供我們使用比如java.util.concurrent.*,以及Universal Image Loader,或者EventBus,所以當設計時首先要看現在的工具能否滿足我們的需求。而不是自己去實現,子曰:不能重復造輪子,就是就是這個道理。

異步時要注意Activity的生命周期

異步時最容易出錯的就是忽略Activity的生命周期。比如,當異步執行完成了,Activity卻退出了前臺,或者已經結束,如果異步完成時要操作UI,那么這種情況下肯定會報錯,具體的錯誤取決于場景。這個問題的解法就是在異步操作完成后要用Activity.isFinishing()來判斷下Activity是否還是alive的。或者設置一個變量來查看Activity是否還在前臺。

另外,即使異步操作中不涉及UI,那么當Activity轉入后臺,或者退出時,也要及時的終止工作線程,否則也會造成Activity的對象無法及時銷毀而最終導致內存泄露。這個問題需要在設計異步task時把可取消考慮進去,當Activity退出前臺時發送消息給線程,讓其終止執行。對于常見的費時操作,比如IO,網絡,復雜計算等在都要考慮取消,每一個小步驟執行前都要判斷取消標志位,以及時終止操作。通常這需要在Activity中持有任務的引用,或者使用Executors來管理任務,或者有一個類似的對象來管理異步任務,當Activity退出時,來終止任務。或者使用EventBus這類工具來降低耦合。

有用的資源

關于Android中的異步已經有了一本專門的書了《Efficient Android Threading》,內容還是比較豐富的,可以看一看。

來自:http://toughcoder.net/blog/2015/05/25/effective-android-asynchrony/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!