Android中Handler的使用

一、Handler的基本实现规则

下面的例子是向Message中传递数值Bundle,然后handler将message传递出去。

Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
updateUIHere();
}
}

new Thread() {
public void run() {
doStuff(); // 执行耗时操作
Message msg = myHandler.obtainMessage();
Bundle b = new Bundle();
b.putString("key", "value");
m.setData(b); // 向消息中添加数据
myHandler.sendMessage(m); // 向Handler发送消息,更新UI
}
}.start();

通过上面的文章,可以对handler的处理机制有一个比较深刻的认识,而我之前的疑问,为什么在handler中post一个线程,也就有了答案。
handler的应用相当一个对多线程管理的机制,通过一个线程的队列(因为可以post多个)来管理这些线程,

 同时通过使用Handler或者HandlerThread来控制,这些线程是要在主线程中执行还是要新开一个线程来执行。


二、例子(1)

1、注意:
只有主线程才可以更新UI,所以如果子线程想要更改UI,就应该通过一个中间类通知主线程更新UI,这个中间类就是Handler(消息处理器)

2、子线程通知主线程更新UI的流程:
(1)、子线程利用handler发送一条消息,消息被放在主线程的消息队列中。
(2)、主线程里面有一个looper消息的轮训器。
(3)、如果轮训器发现了新的消息,调用handlemessage的方法,处理消息。

3、示例代码:
(下面这个程序的意思是将网络上读取出来的图片展示出来)
import java.io.InputStream;
import java.net.HttpURLConnection;
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.widget.EditText;
import android.widget.ImageView;

public class MainActivity extends Activity {

private EditText etUrl;
private ImageView ivIcon;

private Handler handler = new Handler() {


/**
* 接收短信的方法, 执行在主线程中.
* @param msg
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("接收到消息了.");
Bitmap bitmap = (Bitmap) msg.obj;


// 把图片展示到ImageView控件上
ivIcon.setImageBitmap(bitmap);
}
};


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

etUrl = (EditText) findViewById(R.id.et_url);
ivIcon = (ImageView) findViewById(R.id.iv_icon);
}

/**
* 抓去网络图片
* @param v
*/
public void go(View v) {
final String url = etUrl.getText().toString();

// 根据url去抓去图片   bitmap就是android下用来表示图片的
new Thread(new Runnable() {

@Override
public void run() {
Bitmap bitmap = getImageFromNetWork(url);

Message msg = new Message();
msg.obj = bitmap;
System.out.println("发送消息");
handler.sendMessage(msg); // 发送消息
//msg.sendToTarget();同上
//handler.sendMessageDelayed(Message,long);延迟一定时间后,将消息发送到消息队列
//handler.sendMessageAtTime(Message,long)定时将消息发送到消息队列
}
}).start();

}


/**
* 根据url获取图片
* @param url
* @return
*/
private Bitmap getImageFromNetWork(String url) {
try {
// 根据url连接创建一个url对象
URL u = new URL(url);
// 使用URL对象打开一个http协议的连接
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
// 设置请求方法为GET
conn.setRequestMethod("GET"); // 必须得大写
conn.setConnectTimeout(10000); // 设置连接服务器的超时时间为10秒钟, 如果10秒钟还没连接服务器, 那就超时.
conn.setReadTimeout(10000); // 设置读取内容的超时时间为10秒钟

conn.connect(); // 开始连接
int responseCode = conn.getResponseCode(); // 获得状态码
if(responseCode == 200) {
// 访问服务器成功, 获取服务器返回的图片信息.
InputStream is = conn.getInputStream();

Bitmap bitmap = BitmapFactory.decodeStream(is);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


}

三、示例代码(2)

1、
**这里重写handleMessage方法,接受到子线程数据后更新UI**/
private Handler handler=new Handler(){
 @Override
public void handleMessage(Message msg){
switch(msg.what){
case 1:
//关闭
 ImageView view=(ImageView)frameLayout.findViewById(R.id.image);
 view.setImageBitmap(bitmap);
 dialog.dismiss();
break;
 }
 }
 };


2、
//前台ui线程在显示ProgressDialog,
//后台线程在下载数据,数据下载完毕,关闭进度框
 @Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btnFirst:
 dialog= ProgressDialog.show(this,"",
"下载数据,请稍等 …",true,true);
//启动一个后台线程
 handler.post(new Runnable(){
 @Override
public void run() {
//这里下载数据
 try{
 URL url= new URL(params);
 HttpURLConnection conn= (HttpURLConnection)url.openConnection();
 conn.setDoInput(true);
 conn.connect();
 InputStream inputStream=conn.getInputStream();
 bitmap= BitmapFactory.decodeStream(inputStream);
 Message msg=new Message();
 msg.what=1;
 handler.sendMessage(msg);


 }catch (MalformedURLException e1) {
 e1.printStackTrace();
 }catch (IOException e) {
// TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 });
break;
}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值