您的位置:首页 > 其它

Handler消息传递学习笔记

2015-01-30 20:02 316 查看
Android应用中经常需要在多线程中操作UI组件,而多线程操作UI组件会导致安全问题。为了处理这个问题,出现了Handler机制。

使用Handler通常会用到以下函数:

post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnablelong)
handlerMessage(Messagemsg)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageDelayed(Message,long)

Message数据传递:

存放数据
Messagemsg=newMessage();
Bundleb=newBundle();//存放数据
b.putString("color","我的");
msg.setData(b);
myHandler.sendMessage(msg);


接收数据
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
Bundleb=msg.getData();
Stringcolor=b.getString("color");
...
}


最简单的实例:

通过Handler

Handler属于主线程,即UI线程,因此它能够处理UI组件。
publicclassHandlerTestextendsActivity
{
//定义周期性显示的图片的ID
int[]imageIds=newint[]
{
R.drawable.java,
R.drawable.ee,
R.drawable.ajax,
R.drawable.xml,
R.drawable.classic
};
intcurrentImageId=0;
@Override
publicvoidonCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
finalImageViewshow=(ImageView)findViewById(R.id.show);
//位于主线程,相当于普通的函数,等待被调用,负责UI界面的处理。
finalHandlermyHandler=newHandler()
{
@Override
publicvoidhandleMessage(Messagemsg)
{
//如果该消息是本程序所发送的
if(msg.what==0x1233)
{
//动态地修改所显示的图片
show.setImageResource(imageIds[currentImageId++%imageIds.length]);
}
}
};
//新线程,当调用mHandler发送消息时,会自动调用handleMessage()函数
//定义一个计时器,让该计时器周期性地执行指定任务
newTimer().schedule(newTimerTask()
{
@Override
publicvoidrun()
{
//发送空消息
myHandler.sendEmptyMessage(0x1233);
}
},0,1200);
//回调机制:自己发送Message自己接收。
}
}

publicclassHandlerTestextendsActivity{[code]/**Calledwhentheactivityisfirstcreated.*/
privateButtonstartButton;
privateButtonendButton;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//根据id获得控件对象
startButton=(Button)findViewById(R.id.startButton);
endButton=(Button)findViewById(R.id.endButton);
//为控件设置监听器
startButton.setOnClickListener(newStartButtonListener());
endButton.setOnClickListener(newEndButtonListener());
}
classStartButtonListenerimplementsOnClickListener{
publicvoidonClick(Viewv){
//调用Handler的post()方法,将要执行的线程对象放到队列当中
handler.post(updateThread);
}
}
classEndButtonListenerimplementsOnClickListener{
publicvoidonClick(Viewv){
//调用Handler的removeCallbacks()方法,删除队列当中未执行的线程对象
handler.removeCallbacks(updateThread);
}
}
//创建Handler对象
Handlerhandler=newHandler();
//新建一个线程对象
RunnableupdateThread=newRunnable(){
//将要执行的操作写在线程对象的run方法当中
publicvoidrun(){
System.out.println("updateThread");
//调用Handler的postDelayed()方法
//这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象
//第一个参数是Runnable类型:将要执行的线程对象
//第二个参数是long类型:延迟的时间,以毫秒为单位
handler.postDelayed(updateThread,3000);
}
};
}


举例:在新建线程中使用Handler

当点击按钮之后,主线程通过Handler把把数据传递到CalThread线程,CalThread线程在处理完之后将结果通过Toast显示出来。
publicclassCalPrimeextendsActivity
{
staticfinalStringUPPER_NUM="upper";
EditTextetNum;
CalThreadcalThread;
//定义一个线程类
classCalThreadextendsThread
{
publicHandlermHandler;
publicvoidrun()
{
Looper.prepare();
mHandler=newHandler()
{
//定义处理消息的方法
@Override
publicvoidhandleMessage(Messagemsg)
{
if(msg.what==0x123)
{
intupper=msg.getData().getInt(UPPER_NUM);
List<Integer>nums=newArrayList<Integer>();
//计算从2开始、到upper的所有质数
outer:
for(inti=2;i<=upper;i++)
{
//用i处于从2开始、到i的平方根的所有数
for(intj=2;j<=Math.sqrt(i);j++)
{
//如果可以整除,表明这个数不是质数
if(i!=2&&i%j==0)
{
continueouter;
}
}
nums.add(i);
}
//使用Toast显示统计出来的所有质数
Toast.makeText(CalPrime.this,nums.toString()
,Toast.LENGTH_LONG).show();
}
}
};
Looper.loop();
}
}
@Override
publicvoidonCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
etNum=(EditText)findViewById(R.id.etNum);
calThread=newCalThread();
//启动新线程
calThread.start();
}
//为按钮的点击事件提供事件处理函数
publicvoidcal(Viewsource)
{
Stringnum=etNum.getText().toString().trim();
if(!"".equals(num)){
//创建消息
Messagemsg=newMessage();
msg.what=0x123;
Bundlebundle=newBundle();
bundle.putInt(UPPER_NUM,Integer.parseInt(num));
msg.setData(bundle);
//向新线程中的Handler发送消息
calThread.mHandler.sendMessage(msg);
}else{
tv.setText("Pleaseinputanaturalnumber!");
}
}
}


加上新线程将获取的数据传回主线程:
publicclassCalPrimeextendsActivity
{
staticfinalStringUPPER_NUM="upper";
EditTextetNum;
TextViewtv;
CalThreadcalThread;
HandlermyHandler;
//定义一个线程类
classCalThreadextendsThread
{
publicHandlermHandler;
publicvoidrun()
{
Looper.prepare();
mHandler=newHandler()
{
//定义处理消息的方法
@Override
publicvoidhandleMessage(Messagemsg)
{
if(msg.what==0x123)
{
intupper=msg.getData().getInt(UPPER_NUM);
List<Integer>nums=newArrayList<Integer>();
//计算从2开始、到upper的所有质数
outer:
for(inti=2;i<=upper;i++)
{
//用i处于从2开始、到i的平方根的所有数
for(intj=2;j<=Math.sqrt(i);j++)
{
//如果可以整除,表明这个数不是质数
if(i!=2&&i%j==0)
{
continueouter;
}
}
nums.add(i);
}
//使用Toast显示统计出来的所有质数
//Toast.makeText(CalPrime.this,nums.toString(),Toast.LENGTH_LONG).show();
Messagemymsg=newMessage();
Bundleb=newBundle();//存放数据
b.putString("result",nums.toString());
mymsg.setData(b);
mymsg.what=0x1233;
myHandler.sendMessage(mymsg);
}
}
};
Looper.loop();
}
}
@Override
publicvoidonCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
etNum=(EditText)findViewById(R.id.etNum);
tv=(TextView)findViewById(R.id.tv);
calThread=newCalThread();
//启动新线程
calThread.start();
myHandler=newHandler()
{
@Override
publicvoidhandleMessage(Messagemsg)
{
//如果该消息是本程序所发送的
if(msg.what==0x1233)
{
//动态地修改所显示的图片
Bundleb=msg.getData();
Stringresult=b.getString("result");
tv.setText(result.substring(1,result.length()-1));
}
}
};
}
//为按钮的点击事件提供事件处理函数
publicvoidcal(Viewsource)
{
Stringnum=etNum.getText().toString().trim();
if(!"".equals(num)){
//创建消息
Messagemsg=newMessage();
msg.what=0x123;
Bundlebundle=newBundle();
bundle.putInt(UPPER_NUM,Integer.parseInt(num));
msg.setData(bundle);
//向新线程中的Handler发送消息
calThread.mHandler.sendMessage(msg);
}else{
tv.setText("Pleaseinputanaturalnumber!");
}
}
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: