Handler机制整理

Handler机制整理
目录介绍
1.关于handler消息机制图
2.关于handler基本介绍
3.使用handler的几种方法
4.关于handler底层源码解读

1.关于Handler消息机制图

Image.png

2.关于Handler机制基本解读
Message
消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

sendMessage(message);                                    //发送消息
sendEmptyMessage(0);                                     //其实内部实现还是和上面一样
endEmptyMessageAtTime(int what, long uptimeMillis);      //定时发送空消息
sendEmptyMessageDelayed(int what, long delayMillis);     //延时发送空消息
sendMessageAtTime(Message msg, long uptimeMillis);       //定时发送消息
sendMessageDelayed(Message msg, long delayMillis);       //延时发送消息
sendMessageAtFrontOfQueue(Message msg);                  //最先处理消息(慎用)

Handler
处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

MessageQueue
消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
把消息进行排序,排序的依据就是消息要执行的时间

Looper
消息泵,不断地从MessageQueue中抽取Message执行。通过Looper去消息队列取消息
当主线程创建的时候,就会创建一个looper,looper在new的时候会创建一个MessageQueue 。所以,一个线程对应一个Looper一个Looper对应一个MessageQueue
Looper创建之后必须调用loop方法,loop方法中有一个死循环,这个死循环会不断去消息队列里取消息,取出消息之后就会调用handler的handlemessage方法处理消息

Thread
线程,负责调度整个消息循环,即消息循环的执行场所。

3.使用handler的几种方法
1.1主线程中定义Handler,子线程中发消息,通知Handler完成UI更新
Handler对象必须定义在主线程中,如果是多个类直接互相调用,就不是很方便,需要传递content对象或通过接口调用

在主线程中

主线程接收消息处理操作
private Handler myHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what) {
            case 0:
                //更新UI等
                break;
            case 1:
                //更新UI等
                break;
            default:
                break;
        }
    }
};
//开启一个子线程,子线程发送信息
new Thread(
        new Runnable() {
            @Override
            public void run() {
                //处理耗时逻辑
                if(a==1){               //直接发送信息,消息标识中并没有带参数
                    /**
                     *获取消息,尽量用obtainMessage()方法,查看源码发现,该方法节省内存。
                     *不提倡用Messenger msg=new Messenger()这种方法,每次创建一个对象,肯定不节省内存啦!
                     *至于为什么该方法还存在,估计还是有存在的必要吧。(留作以后深入研究)
                     */
                    Message message = myHandler.obtainMessage();
                    message.what = 1;                               //消息标识
                    myHandler.sendMessage(message);                 //发送消息
                }else if(a==2){
                    Message msg = myHandler.obtainMessage();
                    msg.what = 1;                                   //消息标识
                    msg.arg1=2; //存放整形数据,如果携带数据简单,优先使用arg1和arg2,比Bundle节省内存。
                    msg.arg2=3;                                     //存放整形数据
                    Bundle bundle=new Bundle();
                    bundle.putString("dd","abcd");
                    bundle.putInt("love",5);
                    msg.setData(bundle);
                    msg.obj=bundle;                                 //用来存放Object类型的任意对象
                    myHandler.sendMessage(msg);                     //发送消息
                }else if(a==3){
                    Message obtain = Message.obtain();
                    obtain.what = 1;
                    myHandler.sendMessage(obtain);
                }else if(a==4){
                    myHandler.sendEmptyMessage(0);                  //其实内部实现还是和上面一样
                }
            }
        }
).start();

2.1用Activity对象的runOnUiThread方法更新

new Thread() { 
    public void run() { 
    //这儿是耗时操作,完成之后更新UI; 
    runOnUiThread(new Runnable(){ 
        @Override 
        public void run() { 
        //更新UI 
        } 
    }); 
    } 
}.start(); 
如果在非上下文类中(Activity),可以通过传递上下文实现调用;
Activity activity = (Activity) imageView.getContext(); 
activity.runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
    //更新UI 
    imageView.setImageBitmap(bitmap); 
    } 

4.关于handler底层源码解读

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容