1. 程式人生 > >Android Handler(子執行緒Handler)非同步訊息處理機制的妙用(活用訊號量) 建立強大的圖片載入類

Android Handler(子執行緒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. 相關推薦

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

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

    Android通訊模組執行,多執行通訊方式,Handler 與UI Thread的互動,Handler接合執行的使用

    一丶概述 本週的學習計劃是Android通訊模組,內容:單執行緒,多執行緒通訊方式,Handler 與UI Thread的互動,Handler接合子執行緒的使用。 二丶效果演示(原始碼連結見文末) 三丶實現功能 1.演示使用Handler常見崩潰 2.handler更新

    Handler訊息傳遞機制執行中傳遞new Handler和主執行中new Handle傳遞訊息

    > 子執行緒中更新UI new Thread(new Runnable() {         @Override         public void run() {             Looper.prepare();          

    Android可以在執行更新重新整理UI---"假象"

    有時候,我們線上程裡面需要彈框,然而在用Toast彈框後,會出一個Can't create handler inside thread that has not called Looper.prepare()  錯誤。。。。原因很簡單就是因為安卓介面更新的操作需要在主執行緒操作. 實現

    Android可以在執行更新重新整理UI---"假象"

    有時候,我們線上程裡面需要彈框,然而在用Toast彈框後,會出一個Can't create handler inside thread that has not called Looper.prepare()  錯誤。。。。原因很簡單就是因為安卓介面更新的操作需要在主執行緒操

    執行Handler.sendMessage 報錯:Attempt to invoke virtual method 'boolean android.os.Handler.sendMessage

    03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: FATAL EXCEPTION: main 03-17 08:10:18.760 16029-16029/tech.

    Android使用Handler實現執行執行、主執行之間通訊

    今天這篇文章只講一下怎麼使用Handler實現子執行緒與子執行緒之間、子執行緒與主執行緒之間如何進行通訊,關於具體的內部實現因為我也沒研究過,所以這篇文章講不了。 一、子執行緒向主執行緒傳值: 這個實現比較簡單,因為主執行緒自帶Looper機制,所有我們不用

    執行Handler sendMessage 報錯 Attempt to invoke virtual method '

                    03-17 08:10:18.760 16029-16029/tech.androidstudio.tulingdemo E/AndroidRuntime: FATAL EXCEPTION: main03-17 08:10:18.760 16029-16029/tech.and

    Handler執行解析介面

    先在xml介面設定兩個控制元件一個按鈕和一個listview 在原頁面 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle sav

    Looper、Handler執行中的應用

    Looper類:為一個執行緒開啟一個訊息迴圈,裡面有一個訊息佇列,新執行緒是沒有開啟訊息迴圈的,所以需要用到Looper的方法建立訊息迴圈(主執行緒除外,主執行緒會自動為其建立Looper物件,開啟訊息迴圈),MessageQueue存放訊息和事件 Handler

    更新UI的幾種方式?執行與UI執行有哪幾種通訊方式?

    handler sendMessage方式 private Handler handler = new Handler() { public void handleMessage(Message msg) {

    handler通訊(執行傳資料到主執行)

    1.handler通訊小demo 1>.開子執行緒獲取當前的時間,然後每隔10s將獲取時間儲存到檔案中; 2>.在UI執行緒也是每隔10s從檔案中獲取儲存的時間,然後在TextView中做即時展示和ListView中做所有資料的展示。 package com.z

    使用Handler執行中更新UI

    我們知道,使用者的耐性是有極限的。一般來說,一個請求如果2到5秒鐘沒有響應,使用者就會想砸機器。為了優化使用者的互動設計,就不能阻塞UI執行緒,也就是不能在UI執行緒中執行耗時的操作,比如說網路請求。但是這種耗時操作是不可避免的,所以耗時操作只能放到子執行緒中。一個耗時操作

    android-如何在執行中更新ui

    正如我們知道的,android是不讓在子執行緒中更新ui的。在子執行緒中更新ui會直接丟擲異常 Only the original thread that created a view hierarchy can touch its views 那麼這種檢查

    android中開啟執行

    有些東西是需要總結下了。。。在面試過程中,被問到,如何開啟一個子執行緒的時候。。。腦子裡忘得只剩new Thread物件了,還有就是沒有意識到自己是否在主執行緒中做了耗時操作,這些都是很致命的。兜兜轉轉,還是java基礎差惹的禍,咱給補上。 AndroidRu

    執行基礎:多工處理——Fork/Join框架基本使用

    1. 概述在進行系統儲存專題的學習、總結、整理和寫作的過程中感覺有點累了,加上最近在做書稿的第二次校稿工作,系統儲存專題的學習和寫作進度明顯有些滯後,特別是編寫的Ceph MON知識點。所以後續1、2個月的時間打算換一個學習整理方向,之後再繼續恢復系統儲存專題的寫作。換一個什

    android service與執行之淺談

    最近在做一個android的專案,有一個操作是首先將接收的資料處理分析,然後將處理過的資料儲存到資料庫中。這將是一個十分耗時的工作。我直接將這一操作寫在了UI主執行緒中。結果log中提示不要把耗時的工作在主執行緒中完成。於是在網上查閱了一下,發現網上有兩種說法:一種說寫

    Android開發——實現執行更新UI

    Android中執行緒按功能分的話,可以分為兩個,一個是主執行緒(UI執行緒),其他的都是子執行緒 主執行緒不能執行那些耗時過長的程式碼或任務(執行耗時過長的程式碼會出現應用未響應的提示),所以都是使用子執行緒來執行耗時過長的程式碼,比如說下載檔案等任務 一般情況,子執行緒中執行過長的程式碼,都是需要進行更新

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

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

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

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