Android事件处理方法总结-Handler消息处理

来源:互联网 发布:linux 新建文件夹 编辑:程序博客网 时间:2024/05/13 13:49

一、Android中的事件处理方法

事件处理:响应用户UI动作,提高应用程序交互性

1基于监听的事件处理机制

2基于回调的事件处理机制

3Handler消息处理

 

前面我们已经介绍了 Android事件处理方法总结-基于监听 、 基于回调的事件处理,这里我们总结一下 Handler消息处理

 

二、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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    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;public class MainActivity extends Activity implements OnClickListener {private EditText et_url;private Button btg_go;private ImageView img_urlpic;private static final int SUCCESS = 0;private static final int FAIL = 1;private Handler handler = new Handler(){    /* handleMessage主线程接收子线程发送过来的消息 */    @Override    public void 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    protected void 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);    }    @Overridepublic void onClick(View v) {final String picUrl = et_url.getText().toString(); /* 子线程里面处理 连接网络抓取图片的功能   */new Thread(new Runnable() {@Overridepublic void 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


http://blog.csdn.net/yihuiworld 


1 1
原创粉丝点击