Android Handler使用详解

来源:互联网 发布:淘宝小家电 编辑:程序博客网 时间:2024/06/06 06:36

handler是android给我们提供用来更新UI的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它处理消息。

它最根本的目的就是解决多线程并发问题,假设如果在一个Activity当中,有多个线程去更新UI,并且都没有加锁机制,就会产生更新界面错乱。如果对更新UI的操作都进行枷锁处理又会使应用性能下降,所以Android给我们提供了一套更新UI的机制,我们只需要遵循这样的机制就可以了,根本不用去关心多线程问题,多有的更新UI操作,都是在主线程的消息队列当中去轮询处理的。

handler的使用:

1、使用handler更新UI,详细参考:Android Handler使用详解之UI更新

定义handler

private Handler handler = new Handler();

定义Runnable

Runnable runnable = new Runnable() {public void run() {tetxView.setText("cx");}};

启动Runnable

handler.post(runnable);
2、使用handler延时更新UI

前面相同,只有启动时有差别

handler.postDelayed(runnable, 2000);//延时2s更新UI

延时发送通知

handler.sendEmptyMessageDelayed(what, 2000);

3、使用handler消息传递

创建消息,可以创建不同类型的消息(这里arg1、arg2和obj)

Message message = new Message(); //或Message message = handler.obtainMessage();这是也可以用message.sendToTarget();发送消息message.arg1=66;message.arg2=33;message.obj="cx";handler.sendMessage(message);
接收并处理消息
private Handler handler = new Handler(){public void handleMessage(Message msg) {tetxView.setText((String) msg.obj + msg.arg1 + msg.arg2);};};
4、消息延时传递sendMessageDelayed,与上面相同。
5、handler移除功能

例如:在2中的延时更新UI过程中,在延时过程中移除,则UI不再更新。

handler.removeCallbacks(runnable);
6、handler消息拦截

消息接收

private Handler handler = new Handler(new Callback() {@Overridepublic boolean handleMessage(Message msg) {// TODO Auto-generated method stubToast.makeText(getApplicationContext(), "1", 1).show();return true;//返回false,执行完上面的代码在执行下面的;返回true,则不再执行下面的代码}}){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubToast.makeText(getApplicationContext(), "2", 1).show();}};

发送一个空消息

handler.sendEmptyMessage(1);
7、handler原理总结:

Handler负责发送消息,Looper负责接收Handler发送的消息,并直接把消息回传给handler自己,MessageQueue就是一个存储消息的容器。

8、创建与子线程相关的Handler

主线程的Handler中不要执行耗时操作,否则界面会出现卡死现象。

创建主线程Handler

private Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {System.out.println("UI-----------"+Thread.currentThread());};};
创建子线程和子线程Handler
class MyThread extends Thread{public Handler handler;@Overridepublic void run() {// TODO Auto-generated method stubLooper.prepare();//要创建handler必须先创建接收handler消息的Looperhandler=new Handler(){public void handleMessage(android.os.Message msg) {System.out.println("-----------"+Thread.currentThread());};};Looper.loop();//开始循环Looper}};
发送消息
MyThread thread=new MyThread();//定义子线程thread.start();//启动子线程thread.handler.sendEmptyMessage(1);//向子线程Handler发送消息handler.sendEmptyMessage(1);<span style="font-family: Arial, Helvetica, sans-serif;">//向主线程Handler发送消息</span>
9、HandlerThread

在主线程的Handler中传入子线程中定义的Looper时,会出现空指针问题。

定义子线程及子线程中的Handler和Looper

class MyThread extends Thread{public Handler handler;public Looper looper;@Overridepublic void run() {// TODO Auto-generated method stubLooper.prepare();looper=Looper.myLooper();handler=new Handler(){public void handleMessage(android.os.Message msg) {System.out.println("-----------"+Thread.currentThread());};};Looper.loop();}};
启动子线程,创建一个Handler并传入子线程中的Looper
MyThread thread=new MyThread();thread.start();Handler handler=new Handler(thread.looper){public void handleMessage(android.os.Message msg) {System.out.println(msg);};};
运行程序会出现错误,thread.looper为空,因为在主线程中创建Handler时,子线程中的Looper还没有创建,这就是多线程并发的问题。修改上面代码:
HandlerThread thread=new HandlerThread("chenxu");//主要功能就是创建Looper,参数为线程名。thread.start();Handler handler=new Handler(thread.getLooper()){public void handleMessage(android.os.Message msg) {//可执行耗时操作System.out.println(">>>>>>>>>>>>" + Thread.currentThread());//与上面线程名一致};};handler.sendEmptyMessage(1);
这时的handler就相当于是子线程中的handler,即使执行耗时操作也不会出现界面卡顿的现象。
10、主线程与子线程信息交互

import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;public class MainActivity extends Activity {private Handler threadHandler;//主线程handlerHandler handler = new Handler(){public void handleMessage(android.os.Message msg) {Message message = new Message();//向子线程发送消息threadHandler.sendMessageDelayed(message, 1000);System.out.println("main handler");};};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);HandlerThread thread = new HandlerThread("threadHandler");//主要功能就是创建Looper,参数为线程名。thread.start();//子线程handlerthreadHandler = new Handler(thread.getLooper()){public void handleMessage(android.os.Message msg) {Message message = new Message();//向主线程发送消息handler.sendMessageDelayed(message, 1000);System.out.println("threadHandler handler");};};handler.sendEmptyMessage(1);}}

11、其他消息传递方法

发送消息

handler.obtainMessage(1,true).sendToTarget();handler.obtainMessage(2,"str").sendToTarget();
接收消息

Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1:boolean b = (Boolean)msg.obj;break;case 2:String  s = (String)msg.obj;break;}}};

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗眼睛流血水怎么办 石粉粘土干了怎么办 樱花针管笔干了怎么办 想学linux不会c语言怎么办 被摩托车排气管烫伤了怎么办 泡泡糖粘在衣服上怎么办 皮卡书屋办卡怎么办 照证件照齐刘海怎么办 哈挺机床卡刀了怎么办 绝地求生卡在登陆页面怎么办 白鞋子长霉了怎么办 幸福树树干烂了怎么办 花椒树树叶掉落枝干发黑怎么办 茉莉枝干变干了怎么办 冲风了头蒙怎么办 不小心把腰扭了怎么办 白衣服发霉有小黑点怎么办 佛肚竹的枝叶都枯了怎么办 山竹一天吃多了怎么办 水养竹子叶子发黄怎么办 龙竹的竹杆黄了怎么办 散尾竹叶子发黑怎么办 给姐姐打工不发工资怎么办? 水培红掌叶子发黄怎么办 盆竹的叶尖发黄怎么办 养富贵竹水里怎么生小虫怎么办 盆栽金银花叶子全部落掉怎么办 荷花竹根部烂了怎么办 水培绿萝叶子发黄怎么办 大早上的公鸡老打鸣怎么办 紫吊兰叶子变绿怎么办 芙桑花叶子发黄怎么办 长春花长得太高怎么办 四季梅叶子蔫了怎么办 吸财树叶子蔫了怎么办 民族团结手抄报间单有漂亮怎么办 鹦鹉尾巴毛掉了怎么办 羊绒衫领子打太大了怎么办 内裤洗了还有一股味道怎么办 月经下不来内裤上总有脏东西怎么办 夏天外衣薄露出内衣怎么办