Android学习笔记:Handler初步
Handler
Handler,它直接继承自Object,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的MessageQueue中。每个Handler具有一个单独的线程,并且关联到一个消息队列的线程,就是说一个Handler有一个固有的消息队列。当实例化一个Handler的时候,它就承载在一个线程和消息队列的线程,这个Handler可以把Message或Runnable压入到消息队列,并且从消息队列中取出Message或Runnable,进而操作它们。
一下是一个简单的例子。两个按钮只是测试用的。点击按钮后,将改变TextView的文字。
packagecom.jam.testhandler;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;publicclassMainActivityextendsActivity{privateButtonbutton1;privateButtonbutton2;privateTextViewtextView;privateMyHandlerhandler;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);handler=newMyHandler();button1=(Button)findViewById(R.id.button1);button2=(Button)findViewById(R.id.button2);textView=(TextView)findViewById(R.id.textView);button1.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){Threadt=newMyWorkThread();t.start();}});button2.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){TestThreadtt=newTestThread();Threadthread=newThread(tt);thread.start();}});}//集成Thread的方法privateclassMyWorkThreadextendsThread{@Overridepublicvoidrun(){try{Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}Strings="Stringfromworkthread";//这里我没弄清楚obtainMessage和newMessage的区别。//Messagemsg=handler.obtainMessage();Messagemsg=newMessage();msg.obj=s;handler.sendMessage(msg);}}//实现Runnable//注意Runnable代表线程体而不是一个线程privateclassTestThreadimplementsRunnable{@Overridepublicvoidrun(){Runnabler=newRunnable(){@Overridepublicvoidrun(){System.out.println("Thread的名字-->"+Thread.currentThread().getName());}};handler.post(r);}}}
Handler 发送的 message 到队列中后,Looper 拿到后会返回到发送消息的Handler中处理。
Handler拿到后,在这个例子中,由于Handler是在主线程当中,所以这个机制可以另其他线程处理的东西拿到Handler中,再进行UI的修改。
以下是另一种用法,在新的线程中使用Handler
packagecom.example.testhandler2;importandroid.app.Activity;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Looper;importandroid.os.Message;importandroid.util.Log;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.TextView;publicclassMainActivityextendsActivity{privateButtonbutton;privateTextViewtextView;privateHandlerhandler;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button=(Button)findViewById(R.id.button);textView=(TextView)findViewById(R.id.textView);button.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){Messagemsg=newMessage();msg.what=50;handler.sendMessage(msg);}});WorkerThreadworkerThread=newWorkerThread();workerThread.start();}privateclassWorkerThreadextendsThread{@Overridepublicvoidrun(){Looper.prepare();handler=newHandler(){@OverridepublicvoidhandleMessage(Messagemsg){Log.d("msg",""+msg.what);}};Looper.loop();}}}
在点击按钮后,使用handler发送数据,在另一个线程中把数据取出来。
在子线程创建使用Handler要注意固定用法:
先准备Loop
Looper.prepare()
复写Handler的方法handleMessage
Looper.loop
注意:
Thread代表线程
Runnable代表线程体不是一个线程,线程体传入线程才能用
Handler在哪个线程生成,Looper就在哪个线程
Handler.post()方法 将一个Runnable放入Message的callback中,然后传入消息队列。
Loop取出带有Runnable的Message后,判断是否有callback属性,有则执行handleCallback(Message msg),然后在此方法中执行run方法,没有new一个Thread,一般在这个run()方法中写入需要在UI线程上的操作。
用这样的机制可以弥补没有语句块的缺憾。(oc语言)
另外,有两遍关于Handler很好的博文:
Android--多线程之Handler
Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。