android中的handler文档格式.docx
- 文档编号:22586978
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:17
- 大小:25.48KB
android中的handler文档格式.docx
《android中的handler文档格式.docx》由会员分享,可在线阅读,更多相关《android中的handler文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
在实例化Handler的时候,Looper可以是任意线程的,只要有Handler的指针,任何线程也都可以sendMessage。
Handler对于Message的处理不是并发的。
一个Looper只有处理完一条Message才会读取下一条,所以消息的处理是阻塞形式的(handleMessage()方法里不应该有耗时操作,可以将耗时操作放在其他线程执行,操作完后发送Message(通过sendMessges方法),然后由handleMessage()更新UI)。
倒计时程序
利用Timer编写一个倒计时程序,程序使用Timer和TimerTask来完成倒计时,同时使用sendMessages方法发送消息,然后在HanleMessage里更新UI。
Activity布局:
Layout
<
?
xmlversion="
1.0"
encoding="
utf-8"
>
LinearLayoutxmlns:
android="
android:
orientation="
vertical"
layout_width="
fill_parent"
layout_height="
>
TextView
wrap_content"
layout_gravity="
center"
id="
@+id/txt"
/>
Button
@+id/btnStartTime"
text="
开始计时"
80dip"
/Button>
<
@+id/btnStopTime"
停止计时"
SeekBarandroid:
@+id/SeekBar01"
match_parent"
/SeekBar>
/LinearLayout>
这里使用TextView来显示倒计时的时间变化,两个按钮用于控制时间的开始和停止。
SeekBar主要是用于查看线程是否被阻塞(阻塞时无法拖动)。
onCreate
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txt=(TextView)findViewById(R.id.txt);
btnStart=(Button)findViewById(R.id.btnStartTime);
btnStop=(Button)findViewById(R.id.btnStopTime);
Log.d("
ThreadId"
"
onCread:
"
+String.valueOf(Thread.currentThread().getId()));
myHandler=newHandler(this);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
在onCreate方法中初始化元素个元素,myHandler=newHandler(this);
调用的是
Handler(Handler.Callback
callback)构造函数,在回调方法callback中对发送来的消息进行处理(这样我们就不必使用内部类的写法来重写HandleMessage()方法了),因此Activity必须实现
android.os.Handler.Callback
接口。
我们还在将onCreate方法的ThreadId记录在了Log中用以和消息发送、处理时所作的线程进行比较。
发送消息
@Override
publicvoidonClick(Viewv){
switch(v.getId()){
caseR.id.btnStartTime:
startTimer();
break;
caseR.id.btnStopTime:
timer.cancel();
privatesynchronizedvoidstartTimer(){
timer=newTimer();
//TimerTaskupdateTimerValuesTask=newTimerTask(){
//@Override
//publicvoidrun(){
//updateTimerValues();
//}
//
//};
//自定义的CallBack模式。
Task继承自TimerTask
TaskupdateTimerValuesTask=newTask(this);
timer.schedule(updateTimerValuesTask,1000,1000);
//执行耗时的倒计时任务。
privatevoidupdateTimerValues(){
total--;
send:
Messagemsg=newMessage();
Bundledate=newBundle();
//存放数据
date.putInt("
time"
total);
msg.setData(date);
msg.what=0;
myHandler.sendMessage(msg);
//另一种写法
//Messagemsg=myHandler.obtainMessage();
//Bundledate=newBundle();
//date.putInt("
//msg.setData(date);
//msg.what=0;
//msg.sendToTarget();
publicvoidTaskRun(){
updateTimerValues();
实现Button按钮的事件处理以此进入倒计时操作。
这里使用的Timer来执行定时操作(其实我们完全可以另起一个线程)。
Task类继承了TimerTask类,里面增加了一个任务处理接口来实现回调模式,应此Activity需要实现该回调的接口
ITaskCallBack(这样做是因为我比较不喜欢内部类的编写方法)。
ICallBack接口和Task类
publicinterfaceITaskCallBack{
voidTaskRun();
}
publicclassTaskextendsTimerTask{
privateITaskCallBackiTask;
publicTask(ITaskCallBackiTaskCallBack)
{
super();
iTask=iTaskCallBack;
publicvoidsetCallBack(ITaskCallBackiTaskCallBack)
publicvoidrun(){
//TODOAuto-generatedmethodstub
iTask.TaskRun();
这是Java的回调函数的一般写法。
实现CallBack
/**
*实现消息处理
*/
publicbooleanhandleMessage(Messagemsg){
switch(msg.what)
case0:
Bundledate=msg.getData();
txt.setText(String.valueOf(date.getInt("
)));
HandlerMessage:
msgDate:
+String.valueOf(date.getInt("
returnfalse;
可以看到
实现
接口,其实就是对handleMessage()方法进行重写(和内部类的一个区别是,内部类的返回值是Void)。
运行结果
可以看到在onCreate方法中线程的ID是1(UI线程)这与HandlerMessage进行消息处理时是所作的线程ID是一样的,而消息发送的线程ID则为8非UI线程。
使用Threadle进行实现
Activity类
publicclassThreadHandlerrActivityextendsActivityimplementsCallback,
OnClickListener{
privateTextViewtxt;
privateButtonbtnStart,btnStop;
privateHandlermyHandler;
privateTimerThreadtimerThread;
privateintTotal=30;
/**Calledwhentheactivityisfirstcreated.*/
//自定义的线程
timerThread=newTimerThread(myHandler,60);
timerThread.start();
timerThread.stop();
//timerThread.destroy();
自定义的线程类
**
*自定义的线程类,通过传入的Handler,和Total定期执行耗时操作
*@authorlinzijun
*
publicclassTimerThreadextendsThread{
publicintTotal=60;
publicHandlerhandler;
*初始化构造函数
*@parammhandlerhandler用于发送消息
*@paramtotal总周期
publicTimerThread(Handlermhandler,inttotal)
handler=mhandler;
Total=total;
while(true)
Total--;
if(Total<
0)
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
Total);
Thread:
handler.sendMessage(msg);
super.run();
这里继承了Thread类,也可以直接实现Runnable接口。
关于POST
Post的各种方法是把一个Runnable发送给消息队列,它将在到达时进行处理。
POST
publicclassPostHandlerextendsActivityimplementsOnClickListener,Runnable{
privateTimertimer;
privateinttotal=60;
protectedvoidonCreate(BundlesavedInstanceState){
myHandler=newHandler()
publicvoidhandleMessage(Messagemsg){
};
//myHandler.post(this);
myHandler.postDelayed(this,1000);
if(total<
POST:
使用POST的方式是将Runnable一起发送给处理的线程(这里为UI),如果Runnable的操作比较耗时的话那线程将进入阻塞状态。
可以看到先运行Runnable的Run方法然后在进入HandleMessage()。
我还尝试了另一种写法,将TimerThreadPOST过去,运行结果是一样的。
代码
packagezijunlin.me;
importjava.util.Timer;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.TextView;
publicclassPostHandlerextendsActivityimplementsOnClick
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 中的 handler