Android事件處理方法總結-Handler訊息處理
一、Android中的事件處理方法
事件處理:響應使用者UI動作,提高應用程式互動性
1、基於監聽的事件處理機制
2、基於回撥的事件處理機制
3、Handler訊息處理
二、Handler訊息傳遞機制詳解
1、為什麼要使用Handler訊息傳遞
1).Android出於效能考慮,UI執行緒(主執行緒)是非執行緒安全的,為了避免執行緒安全問題,Android規定“ 只允許UI執行緒(即主執行緒)修改程式介面裡面的UI元件”
但是
有時候非UI執行緒業務可能也需要根據需求改變UI介面內容時,這時就可以利用Handler訊息傳遞,子執行緒傳送Handler Message給UI執行緒,通知UI執行緒去改變UI元件
2).Android主執行緒一般不操作 複雜業務邏輯、請求網路等耗時操作,這些操作必須在新的子執行緒裡面,否則可能會引起ANR異常
2、Handler訊息傳遞原理
4個主要參與物件:
Handler:訊息傳送接收處理類。負責從新啟動的執行緒中傳送訊息,在主執行緒中獲取並處理訊息
Message:訊息物件,即Handler接收和處理的訊息物件
MessageQuene:訊息佇列,Message存取於MessageQuene
Looper:每個執行緒只擁有一個Looper,以先進先出的方式負責從MessageQuene訊息佇列裡面讀取Message交由Handler處理
3、Handler訊息處理應用例項
Handler處理訊息應用步驟
Ⅰ.主執行緒建立一個Handler,用於訊息處理
Ⅱ.子執行緒傳送訊息
Ⅲ.主執行緒接收並處理訊息
應用例項:讀取網路圖片
佈局檔案 activity_main.xml
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context=".MainActivity">
- <EditText
- android:id="@+id/et_url"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:inputType="textUri"
- android:singleLine="true"
- android:text="http://pic39.nipic.com/20140320/2531170_111310894000_2.jpg"/>
- <Button
- android:id="@+id/btg_go"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="開啟網路圖片"/>
- <ImageView
- android:id="@+id/img_urlpic"
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"/>
- </LinearLayout>
示例程式碼 MainActivity.java
- package com.yihui.handlermessage;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ImageView;
- import android.widget.Toast;
- publicclass MainActivity extends Activity implements OnClickListener {
- private EditText et_url;
- private Button btg_go;
- private ImageView img_urlpic;
- privatestaticfinalint SUCCESS = 0;
- privatestaticfinalint FAIL = 1;
- private Handler handler = new Handler(){
- /* handleMessage主執行緒接收子執行緒傳送過來的訊息 */
- @Override
- publicvoid handleMessage(Message msg) {
- super.handleMessage(msg);
- switch(msg.what){
- case FAIL:
- Toast.makeText(MainActivity.this, "讀取網路圖片失敗!", 0).show();
- break;
- case SUCCESS:
- img_urlpic.setImageBitmap((Bitmap) msg.obj); //UI主執行緒裡面更新UI資訊
- break;
- default:
- break;
- }
- }
- };
- @Override
- protectedvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- et_url = (EditText) findViewById(R.id.et_url);
- btg_go = (Button) findViewById(R.id.btg_go);
- img_urlpic = (ImageView) findViewById(R.id.img_urlpic);
- btg_go.setOnClickListener(this);
- }
- @Override
- publicvoid onClick(View v) {
- final String picUrl = et_url.getText().toString();
- /* 子執行緒裡面處理 連線網路抓取圖片的功能 */
- new Thread(new Runnable() {
- @Override
- publicvoid run() {
- Bitmap netBitmap = getBitmapFromNet(picUrl);
- Message msg = new Message();
- if(netBitmap == null) {
- msg.what = FAIL;
- } else {
- msg.what = SUCCESS;
- msg.obj = netBitmap;
- }
- handler.sendMessage(msg);
- }
- }).start();
- }
- /* 從URL讀取圖片資訊 */
- private Bitmap getBitmapFromNet(String urlAddr){
- Bitmap netBitmap = null;
- HttpURLConnection httpConn = null;
- try {
- URL url = new URL(urlAddr);
- httpConn = (HttpURLConnection) url.openConnection();
- httpConn.setRequestMethod("GET");
- httpConn.setConnectTimeout(30000);
- httpConn.setReadTimeout(10000);
- httpConn.connect();
- /* 讀取成功 */
- if(200 == httpConn.getResponseCode()) {
- InputStream is = httpConn.getInputStream();
- netBitmap = BitmapFactory.decodeStream(is);
- }
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally{
- if(httpConn != null) {
- httpConn.disconnect();
- httpConn = null;
- }
- }
- return netBitmap;
- }
- }
示例效果
Ps:這裡讀取的是網路圖片,所以在AndroidManifest.xml清單檔案裡面記得新增讀取網路的許可權 android.permission.INTERNET