Android 異步加載數據方式整理

在 Android 中,由于主線程負責維護 UI,不能被阻塞,那么在通過磁盤或者網絡進行異步加載數據的時候就需要使用多線程了。以下是我整理的幾種使用多線程執行異步操作的方式,如有紕漏歡迎指正。

  1. Handler

    Android 中多線程通信基本的方式是使用 Handler 機制,基本使用方式如下。

    //init handler on the original thread
    class OriginalThread extends Thread {
     public Handler mHandler;
     public void run() {
       Looper.prepare();
       mHandler = new Handler() {
         public void handleMessage(Message msg) {
             // process incoming messages here
         }
       };
       Looper.loop();
     }
    }
    //send message to the original thread
    mHandler.post(Runnable);
    mHandler.postAtTime(Runnable, long);
    mHandler.postDelayed(Runnable, long);
    mHandler.sendEmptyMessage(int);
    mHandler.sendMessage(Message);
    mHandler.sendMessageAtTime(Message, long);
    mHandler.sendMessageDelayed(Message, long);
    

    系統還內置了AsyncQueryHandler 輔助子類,方便使用 ContentResolver 進行異步查詢操作。

    關于 Handler,需要注意的是,當 Handler 被聲明為 Activity 的非靜態內部類時, Handler 會持有外部 Activity 實例的引用,Handler 生命周期比 Activity 長時會導致 Activity 實例不能被正常釋放,從而引起內存泄漏。一種解決方式是將 Handler 聲明為 Activity 的靜態內部類或者單獨的類,在 Handler 內部使用 WeakReference/SoftReference 保存對 Activity的引用,既能訪問 Activity 的 View 更新 UI,又可以避免內存泄漏。

  2. AsyncTask

    AsyncTask 方式是官方提供的用來簡化手動寫 Handler 的一種異步機制,其內部仍使用 Handler 實現。

    需要繼承AsyncTask<Params, Progress, Result>類,重寫doInBackground,onPostExecute等回調方法,使用的時候調用 execute 方法(只能在 UI 線程調用)傳入參數就可以方便的執行 IO 或網絡等耗時操作并在操作完成時更新 UI。

    使用 AsyncTask 同樣需要注意內存泄漏問題。

  3. Activity.runOnUiThread(Runnable action)

    算是 Handler 方式的一種語法糖吧,使用了 Activity 自身維護的 一個 mHandler 實例,便于在 UI 線程執行操作,比如異步獲取數據后更新 UI。

  4. Loader

    Loader 是在 Android 3.0 引入的用于在 Activity 和 Fragment 中簡化異步加載數據的方式。

    系統提供了 AsyncTaskLoader<D> 和 CursorLoader 兩個子類。

  5. View.post(Runnable action)/View.postDelayed(Runnable action, long delayMillis)

  6. RxJava

    使用 RxJava 可以方便地進行多線程調度,通過調用 Observable.subscribeOn 和 Observable.observeOn,并使用 Schedulers.io() 和 Schedulers.mainThread() 等工廠方法傳入參數即可自由切換線程。

  7. EventBus

    使用 EventBus 可以在任意線程發布數據,并通過訂閱方法的命名約定規定在何種線程執行訂閱的回調方法。

    // Called in the same thread (default)
    public void onEvent(MessageEvent event) {
     log(event.message);
    }
    // Called in Android UI's main thread
    public void onEventMainThread(MessageEvent event) {
     textField.setText(event.message);
    }
    // Called in the background thread
    public void onEventBackgroundThread(MessageEvent event){
     saveToDisk(event.message);
    }
    // Called in a separate thread
    public void onEventAsync(MessageEvent event){
     backend.send(event.message);
    }
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 文章獨家授權公眾號:碼個蛋更多分享:http://www.cherylgood.cn 談到Android開發,就離...
    Angels_安杰閱讀 1,640評論 0 3
  • 異步消息處理線程啟動后會進入一個無限的循環體之中,每循環一次,從其內部的消息隊列中取出一個消息,然后回調相應的消息...
    cxm11閱讀 6,444評論 2 39
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,833評論 25 708
  • 你真美麗……不,你不是「美麗」,「美麗」太冰冷了;你真「美好」—— 你是美好的,因為你不但美麗,而且溫暖。
    郭綠獅閱讀 252評論 0 2
  • 流浪的云 相思的雨 你可懂我的思念 沒關系 我會接住你 在最美的季節里
    來自俄羅斯的大油條閱讀 128評論 0 0