一、Android中的事件处理方法
事件处理:响应用户UI动作,提高应用程序交互性
1、基于监听的事件处理机制
2、基于回调的事件处理机制
3、Handler消息处理
前面我们已经介绍了 Android事件处理方法总结-基于监听 、 基于回调的事件处理,这里我们总结一下 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
<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);
}
@Override
public void onClick(View v) {
final String picUrl = et_url.getText().toString();
/* 子线程里面处理 连接网络抓取图片的功能 */
new Thread(new Runnable() {
@Override
public 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