1. 程式人生 > >Android事件處理方法總結-Handler訊息處理

Android事件處理方法總結-Handler訊息處理

一、Android中的事件處理方法

事件處理:響應使用者UI動作,提高應用程式互動性

1基於監聽的事件處理機制

2基於回撥的事件處理機制

3Handler訊息處理

二、Handler訊息傳遞機制詳解

1為什麼要使用Handler訊息傳遞

    1).Android出於效能考慮,UI執行緒(主執行緒)是非執行緒安全的,為了避免執行緒安全問題,Android規定“ 只允許UI執行緒(即主執行緒)修改程式介面裡面的UI元件”

          但是

          有時候非UI執行緒業務可能也需要根據需求改變UI介面內容時,這時就可以利用Handler訊息傳遞,子執行緒傳送Handler Message給UI執行緒,通知UI執行緒去改變UI元件

    2).Android主執行緒一般不操作 複雜業務邏輯、請求網路等耗時操作,這些操作必須在新的子執行緒裡面,否則可能會引起ANR異常

2Handler訊息傳遞原理

   4個主要參與物件:

     Handler:訊息傳送接收處理類。負責從新啟動的執行緒中傳送訊息,在主執行緒中獲取並處理訊息

     Message:訊息物件,即Handler接收和處理的訊息物件

         MessageQuene:訊息佇列,Message存取於MessageQuene

     Looper:每個執行緒只擁有一個Looper,以先進先出的方式負責從MessageQuene訊息佇列裡面讀取Message交由Handler處理

           

3Handler訊息處理應用例項

   Handler處理訊息應用步驟

      Ⅰ.主執行緒建立一個Handler,用於訊息處理

      Ⅱ.子執行緒傳送訊息

      Ⅲ.主執行緒接收並處理訊息

     應用例項:讀取網路圖片

       佈局檔案 activity_main.xml

  1. <LinearLayoutxmlns: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.     android:orientation="vertical"
  6.     android:paddingBottom="@dimen/activity_vertical_margin"
  7.     android:paddingLeft="@dimen/activity_horizontal_margin"
  8.     android:paddingRight="@dimen/activity_horizontal_margin"
  9.     android:paddingTop="@dimen/activity_vertical_margin"
  10.     tools:context=".MainActivity">
  11.     <EditText
  12.         android:id="@+id/et_url"
  13.         android:layout_width="match_parent"
  14.         android:layout_height="wrap_content"
  15.         android:inputType="textUri"
  16.         android:singleLine="true"
  17.         android:text="http://pic39.nipic.com/20140320/2531170_111310894000_2.jpg"/>
  18.     <Button
  19.         android:id="@+id/btg_go"
  20.         android:layout_width="match_parent"
  21.         android:layout_height="wrap_content"
  22.         android:text="開啟網路圖片"/>
  23.     <ImageView
  24.         android:id="@+id/img_urlpic"
  25.         android:layout_width="match_parent"
  26.         android:layout_height="0dip"
  27.         android:layout_weight="1"/>
  28. </LinearLayout>

       示例程式碼 MainActivity.java

  1. package com.yihui.handlermessage;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.net.HttpURLConnection;  
  5. import java.net.MalformedURLException;  
  6. import java.net.URL;  
  7. import android.app.Activity;  
  8. import android.graphics.Bitmap;  
  9. import android.graphics.BitmapFactory;  
  10. import android.os.Bundle;  
  11. import android.os.Handler;  
  12. import android.os.Message;  
  13. import android.view.View;  
  14. import android.view.View.OnClickListener;  
  15. import android.widget.Button;  
  16. import android.widget.EditText;  
  17. import android.widget.ImageView;  
  18. import android.widget.Toast;  
  19. publicclass MainActivity extends Activity implements OnClickListener {  
  20.     private EditText et_url;  
  21.     private Button btg_go;  
  22.     private ImageView img_urlpic;  
  23.     privatestaticfinalint SUCCESS = 0;  
  24.     privatestaticfinalint FAIL = 1;  
  25.     private Handler handler = new Handler(){  
  26.         /* handleMessage主執行緒接收子執行緒傳送過來的訊息 */
  27.         @Override
  28.         publicvoid handleMessage(Message msg) {  
  29.             super.handleMessage(msg);  
  30.             switch(msg.what){  
  31.                 case FAIL:  
  32.                     Toast.makeText(MainActivity.this"讀取網路圖片失敗!"0).show();  
  33.                     break;  
  34.                 case SUCCESS:  
  35.                     img_urlpic.setImageBitmap((Bitmap) msg.obj);    //UI主執行緒裡面更新UI資訊
  36.                     break;  
  37.                 default:  
  38.                     break;  
  39.             }  
  40.         }  
  41.     };  
  42.     @Override
  43.     protectedvoid onCreate(Bundle savedInstanceState) {  
  44.         super.onCreate(savedInstanceState);  
  45.         setContentView(R.layout.activity_main);  
  46.         et_url = (EditText) findViewById(R.id.et_url);  
  47.         btg_go = (Button) findViewById(R.id.btg_go);  
  48.         img_urlpic = (ImageView) findViewById(R.id.img_urlpic);  
  49.         btg_go.setOnClickListener(this);  
  50.     }  
  51.     @Override
  52.     publicvoid onClick(View v) {  
  53.         final String picUrl = et_url.getText().toString();   
  54.         /* 子執行緒裡面處理 連線網路抓取圖片的功能   */
  55.         new Thread(new Runnable() {  
  56.             @Override
  57.             publicvoid run() {  
  58.                 Bitmap netBitmap = getBitmapFromNet(picUrl);  
  59.                 Message msg = new Message();  
  60.                 if(netBitmap == null) {  
  61.                     msg.what = FAIL;  
  62.                 } else {  
  63.                     msg.what = SUCCESS;  
  64.                     msg.obj = netBitmap;  
  65.                 }  
  66.                 handler.sendMessage(msg);  
  67.             }  
  68.         }).start();  
  69.     }  
  70.     /* 從URL讀取圖片資訊 */
  71.     private Bitmap getBitmapFromNet(String urlAddr){  
  72.         Bitmap netBitmap = null;  
  73.         HttpURLConnection httpConn = null;  
  74.         try {  
  75.             URL url = new URL(urlAddr);  
  76.             httpConn = (HttpURLConnection) url.openConnection();  
  77.             httpConn.setRequestMethod("GET");  
  78.             httpConn.setConnectTimeout(30000);  
  79.             httpConn.setReadTimeout(10000);  
  80.             httpConn.connect();  
  81.             /* 讀取成功 */
  82.             if(200 == httpConn.getResponseCode()) {  
  83.                 InputStream is =  httpConn.getInputStream();  
  84.                 netBitmap = BitmapFactory.decodeStream(is);  
  85.             }  
  86.         } catch (MalformedURLException e) {  
  87.             e.printStackTrace();  
  88.         } catch (IOException e) {  
  89.             e.printStackTrace();  
  90.         } finally{  
  91.             if(httpConn != null) {  
  92.                 httpConn.disconnect();  
  93.                 httpConn = null;  
  94.             }  
  95.         }  
  96.         return netBitmap;  
  97.     }  
  98. }  

        示例效果

        

  Ps:這裡讀取的是網路圖片,所以在AndroidManifest.xml清單檔案裡面記得新增讀取網路的許可權 android.permission.INTERNET