1. 程式人生 > >LIFO和FIFO——Handler 非同步訊息處理機制的妙用 建立強大的圖片載入類

LIFO和FIFO——Handler 非同步訊息處理機制的妙用 建立強大的圖片載入類

最近建立了一個群,方便大家交流,群號:55032675

上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理機制不僅僅是在MainActivity中更新UI,可以用到別的地方,最近也一直在考慮這個問題,有幸,想出來一個實際的案例,將非同步訊息處理機制用到大量圖片的載入的工具類中,其實也特別希望可以寫一篇關於大量圖片載入的文章,終於有機會了~先簡單介紹一下:

1、概述

一般大量圖片的載入,比如GridView實現手機的相簿功能,一般會用到LruCache,執行緒池,任務佇列等;那麼非同步訊息處理可以用哪呢?

1、用於UI執行緒當Bitmap載入完成後更新ImageView

2、在圖片載入類初始化時,我們會在一個子執行緒中維護一個Loop例項,當然子執行緒中也就有了MessageQueue,Looper會一直在那loop停著等待訊息的到達,當有訊息到達時,從任務佇列按照佇列排程的方式(FIFO,LIFO等),取出一個任務放入執行緒池中進行處理。

簡易的一個流程:當需要載入一張圖片,首先把載入圖片加入任務佇列,然後使用loop執行緒(子執行緒)中的hander傳送一個訊息,提示有任務到達,loop()(子執行緒)中會接著取出一個任務,去載入圖片,當圖片載入完成,會使用UI執行緒的handler傳送一個訊息去更新UI介面。

說了這麼多,大家估計也覺得雲裡來霧裡去的,下面看實際的例子。

2、相簿功能的實現

該程式首先掃描手機中所有包含圖片的資料夾,最終選擇圖片最多的資料夾,使用GridView顯示其中的圖片

1、佈局檔案

  1. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2.     xmlns:tools="http://schemas.android.com/tools"
  3.     android:layout_width="match_parent"
  4.     android:layout_height
    ="match_parent">
  5.     <GridView
  6.         android:id="@+id/id_gridView"
  7.         android:layout_width="match_parent"
  8.         android:layout_height="match_parent"
  9.         android:cacheColorHint="@android:color/transparent"
  10.         android:columnWidth="90dip"
  11.         android:gravity="center"
  12.         android:horizontalSpacing="20dip"
  13.         android:listSelector="@android:color/transparent"
  14.         android:numColumns="auto_fit"
  15.         android:stretchMode="columnWidth"
  16.         android:verticalSpacing="20dip">
  17.     </GridView>
  18. </RelativeLayout>

佈局檔案相當簡單就一個GridView

2、MainActivity

  1. package com.example.zhy_handler_imageloader;  
  2. import java.io.File;  
  3. import java.io.FilenameFilter;  
  4. import java.util.Arrays;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import android.app.Activity;  
  8. import android.app.ProgressDialog;  
  9. import android.content.ContentResolver;  
  10. import android.database.Cursor;  
  11. import android.net.Uri;  
  12. import android.os.Bundle;  
  13. import android.os.Environment;  
  14. import android.os.Handler;  
  15. import android.provider.MediaStore;  
  16. import android.widget.GridView;  
  17. import android.widget.ImageView;  
  18. import android.widget.ListAdapter;  
  19. import android.widget.Toast;  
  20. publicclass MainActivity extends Activity  
  21. {  
  22.     private ProgressDialog mProgressDialog;  
  23.     private ImageView mImageView;  
  24.     /** 
  25.      * 儲存資料夾中的圖片數量 
  26.      */
  27.     privateint mPicsSize;  
  28.     /** 
  29.      * 圖片數量最多的資料夾 
  30.      */
  31.     private File mImgDir;  
  32.     /** 
  33.      * 所有的圖片 
  34.      */
  35.     private List<String> mImgs;  
  36.     private GridView mGirdView;  
  37.     private ListAdapter mAdapter;  
  38.     /** 
  39.      * 臨時的輔助類,用於防止同一個資料夾的多次掃描 
  40.      */
  41.     private HashSet<String> mDirPaths = new HashSet<String>();  
  42.     private Handler mHandler = new Handler()  
  43.     {  
  44.         publicvoid handleMessage(android.os.Message msg)  
  45.         {  
  46.             mProgressDialog.dismiss();  
  47.             mImgs = Arrays.asList(mImgDir.list(new FilenameFilter()  
  48.             {  
  49.                 @Override
  50.                 publicboolean accept(File dir, String filename)  
  51.                 {  
  52.                     if (filename.endsWith(".jpg"))  
  53.                         returntrue;  
  54.                     returnfalse;  
  55.                 }  
  56.             }));  
  57.             /** 
  58.              * 可以看到資料夾的路徑和圖片的路徑分開儲存,極大的減少了記憶體的消耗; 
  59.              */
  60.             mAdapter = new MyAdapter(getApplicationContext(), mImgs,  
  61.                     mImgDir.getAbsolutePath());  
  62.             mGirdView.setAdapter(mAdapter);  
  63.         };  
  64.     };  
  65.     @Override
  66.     protectedvoid onCreate(Bundle savedInstanceState)  
  67.     {  
  68.         super.onCreate(savedInstanceState);  
  69.         setContentView(R.layout.activity_main);  
  70.         mGirdView = (GridView) findViewById(R.id.id_gridView);  
  71.         getImages();  
  72.     }  
  73.     /** 
  74.      * 利用ContentProvider掃描手機中的圖片,此方法在執行在子執行緒中 完成圖片的掃描,最終獲得jpg最多的那個資料夾 
  75.      */
  76.     privatevoid getImages()  
  77.     {  
  78.         if (!Environment.getExternalStorageState().equals(  
  79.                 Environment.MEDIA_MOUNTED))  
  80.         {  
  81.             Toast.makeText(this"暫無外部儲存", Toast.LENGTH_SHORT).show();  
  82.             return;  
  83.         }  
  84. 相關推薦

    LIFOFIFO——Handler 非同步訊息處理機制 建立強大圖片載入

    最近建立了一個群,方便大家交流,群號:55032675 上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理機制不僅

    Android Handler 非同步訊息處理機制 建立強大圖片載入

                    最近建立了一個群,方便大家交流,群號:55032675上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理

    Android Handler 非同步訊息處理機制三:手法 建立強大圖片載入

    上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理機制不僅僅是在MainActivit

    Handler非同步訊息處理機制的原始碼分析

    1. Handler非同步訊息處理機制 主執行緒不能進行耗時操作 (會發生ANR異常) 子執行緒不能更新UI的操作 (因為會報異常——>只有產生該控制元件的執行緒才能操作該控制元件。) 那麼 , 要在子執行緒請求資料,然後將資料傳送到主執行緒中更新

    Android Handler 非同步訊息處理機制 建立強大圖片載入【轉】

    上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後,提出可以把非同步訊息處理機制不僅僅是在MainActiv

    Android非同步訊息處理機制:Looper、Handler、Message

    1 簡介 Handler,Looper,Message這三者都與Android非同步訊息處理執行緒相關, Looper:負責建立一個MessageQueue,然後進入一個無限迴圈體不斷從該MessageQueue中讀取訊息; Handler:訊息建立者,一個或者多個

    (轉載)Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係

    很多人面試肯定都被問到過,請問Android中的Looper , Handler , Message有什麼關係?本篇部落格目的首先為大家從原始碼角度介紹3者關係,然後給出一個容易記憶的結論。 1、 概述 Handler 、 Looper 、Message

    Android非同步訊息處理機制 handler

    我們都知道,Android UI是執行緒不安全的,如果在子執行緒中嘗試進行UI操作,程式就有可能會崩潰。相信大家在日常的工作當中都會經常遇到這個問題,解決的方案應該也是早已爛熟於心,即建立一個Message物件,然後藉助Handler傳送出去,之後在Handler的han

    android中 非同步訊息處理機制Handler

    這時就需要Handler了,修改MainActivity如下:public class MainActivity extends AppCompatActivity { public static final int UPDATE_TEXT =1 ; @Override protec

    Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係

    很多人面試肯定都被問到過,請問Android中的Looper , Handler , Message有什麼關係?本篇部落格目的首先為大家從原始碼角度介紹3者關係,然後給出一個容易記憶的結論。1、 概述Handler 、 Looper 、Message 這三者都與Android

    Android Handler(子執行緒Handler非同步訊息處理機制(活訊號量) 建立強大圖片載入

    最近建立了一個群,方便大家交流,群號:55032675 上一篇部落格介紹了Android非同步訊息處理機制,如果你還不瞭解,可以看:Android 非同步訊息處理機制 讓你深入理解 Looper、Handler、Message三者關係 。那篇部落格的最後

    Android非同步訊息處理機制Handler

    很多人第一次接觸Handler可能是因為一句話”子執行緒不能操作ui”,那子執行緒能不能操作ui呢?我們在這裡不多討論(其實是可以的,但是執行緒不安全),我們來分析下handler是如何運轉起來的。 一般用法都是在“主執行緒”中new一個handler

    android 非同步訊息處理機制 — AHandler

    1. 引入 ALooper、AHandler、AMessage 在 android multimedia stagefright 的框架程式碼中,通篇都是這幾個類的身影,所以熟悉 android 多媒體框架的第一步必須理解這幾個類的含義。 這幾個類是為了實現非同步訊息機制而設計的

    Android非同步訊息處理機制詳解及原始碼分析

    PS一句:最終還是選擇CSDN來整理髮表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支援MarkDown語法了,牛逼啊! 【工匠若水 http://blog.csdn.net/yanbober 轉載煩請註明出處,尊重分享成果】 最近相對來說比較閒,加上養病,所

    Android中的非同步訊息處理機制

    這也是Android中老生常談的一個話題了,它本身並不是很複雜,可是面試官比較喜歡問。本文就從原始碼再簡單的理一下這個機制。也可以說是理一下Handler、Looper、MessageQueue之間的關係。 單執行緒中的訊息處理機制的實現 首先我們以Looper.java原始碼中給出的一個例子來

    解析非同步訊息處理機制

     Android 中的非同步訊息處理主要有四部分組成:Meeage、Handler、MessageQueue 和 Looper。其中Meeage 是執行緒之間傳遞的訊息,它可以攜帶少量的資訊,用於在不同執行緒之間交換資料。Handler是傳送和處理訊息的。傳送訊息一般是使用

    Android之非同步訊息處理機制詳解

    一、在子執行緒中更新UI概述 和許多其他的GUI 庫一樣,Android 的UI 也是執行緒不安全的。也就是說,如果想要更新應用程式裡的UI 元素,則必須在主執行緒中進行,否則就會出現異常。但是有些時候,我們必須在子執行緒裡去執行一些耗時任務,然後根據任務的執

    深入理解Android非同步訊息處理機制

    一。概述   Android 中的非同步訊息處理主要分為四個部分組成,Message、Hndler、MessageQueue 和 Looper。其關係如下圖所示:     1. Message 是執行緒之間傳遞的訊息,它可以在內部攜帶少量資訊,用於在不同執行緒之間交換資料。   2. Messag

    android非同步訊息處理機制

     android非同步訊息處理主要由四部分組成:Handler,Looper,Message,MessageQueue​ Message:執行緒之間傳遞的訊息,可以在內部攜帶少量訊息 MessageQueue: Looper:每個執行緒有且最多隻能有一個Looper物件

    Android非同步訊息處理機制的原始碼分析

    1、背景 相信做過一段時間的Android開發都瞭解,當我們在子執行緒中更新UI時會丟擲異常,導致程式崩潰,Android4.0之後只允許在UI執行緒中更新介面,但是我們也不能再UI執行緒中處理耗時操作,那樣會導致應用程式無響應(即出現ANR)。 那如果想解