Android---消息机制总结

本文详细介绍了Android的消息机制,重点讨论了Handler、Looper和MessageQueue的作用及工作原理。Handler用于发送和处理消息,Looper作为消息循环不断从MessageQueue中取出消息,而MessageQueue作为消息容器,采用单链表存储。此外,文章还提到了在不同场景下更新UI的多种方式,如handler.post()、runOnUiThread等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息机制是什么?

android的消息机制主要是指Handler的运行机制。

handler 是什么?

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

为什么使用handler

android设计的时候就封装了一套这样的消息创建 传递 处理机制 否则就会抛出异常的。主要原因就是为了解决在子线程中无法访问UI的矛盾。

消息队列

消息队列在Android中指的是MessageQueue.其中主要包含两个操作:插入和读取。读取操作本身会伴随着删除操作(对应的方法为:enqueueMessage和N=next)。
尽管MessageQueue叫做消息队列,但是它的内部实现并不是用的队列,实际上是通过一个单链表的数据结构来维护消息列表。
扩展:
enqueueMessage主要操作就是单链表的插入操作。
next:是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞在这里。当有新消息到来时,next方法会返回这条消息并将它从单链表中移除。

Looper的工作原理

Looper在Android的消息机制中扮演者消息循环的角色,他会不停的从MessageQueue中查看是否有新的消息,如果有新的消息就会立即处理,否则一直阻塞在那里。
创建Loop的方法: Looper.prepare(); //So easy
退出Loop的方法: Looper.quit();
查阅了Looper的源码以后发现,他的工作工程比较好理解,loop方法是一个死循环,跳出死循环的方式是next方法返回null。next方法是一个阻塞操作,当没有消息时,next方法会一直阻塞在那里,导致了loop方法也一直阻塞在那里。
如果有了一条消息,Looper会处理这个消息:msg.target.dispatchMessage(msg);
这里的msg.target是发送这条消息的Handler对象,这样Hundler发送的消息最终又交给他的dispatchMessage方法来处理的。

handler的工作原理

Handler的工作主要包含消息的发送和接受过程。
Handler发送消息的过程仅仅是向消息队列中插入了一条消息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理了,最终消息由Looper交给Handler处理,即Handler的dispatchMessage方法会被调用,这时Handler就进入了处理消息的阶段。

handler的用法

//第一种用法
public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Handler handler=new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView= (TextView) findViewById(R.id.textview);

        //通过handler来更新UI
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.setText("你是我的小苹果");
            }
        });

    }
}
//第二种用法 是一个有延时的Handler
handler.postDelayed(Runnable ,long)
handler.postDelayed(mRunnable,1000)   设置handler的延期时间
//第三种用法 handlerMessage
handlerMessage
private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
    }
};
// handler.sendMessage(message);  方法来发送

发送Message的时候方法

一种方法是

Message message=handler.obtainMessage();

从此获得一个message对象

第二种方法是

Message message=new Message();
message.arg1=99;
message.arg2=100;
message.obj=一个类的对象;

移除一个handler

handler.removeCallbacks(Runnable);

handler的截获

private Handler handler=new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        //当返回值为true的时候 是可以截获接受的handler的
        return false;
    }
});

为什么只能通过 handler更新UI

handler
封装了消息的发送 ,主要包括消息发送给谁 ,内部跟Looper进行关联
例message.arg1
looper
内部包括一个消息队列MessageQueue handler发送的消息都保留在这个对流盅
looper.Looper 方法 一个死循环 不断的从MessageQueue中取消息
messagequeue
消息队列 可以添加消息也可以处理消息

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

自定义线程与线程相关的Handler

class MyThread extends Thread{
    public Handler handler;

    @Override
    public void run() {
        Looper.prepare();
        handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                Log.e("-----","我是自定义线程"+Thread.currentThread())
            }
        };
        Looper.loop();
    }
}

HandlerThread

避免空指针的问题则使用HandlerThread

private HandlerThread thread;
private Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);
    //设置启动线程的名字
    thread=new HandlerThread("handler thread");
    thread.start();
    handler=new Handler(thread.getLooper()){
        @Override
        public void handleMessage(Message msg) {
            Log.e("-----","当前线程是"+Thread.currentThread());
        }
    };
    handler.sendEmptyMessage(1);
}

Android中更新UI的几种方式

第一种方式 handler.post();

private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
    }
};
private TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main3);
    textView= (TextView) findViewById(R.id.textview1);
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            handler.post(new Runnable() {
                @Override
                public void run() {
                    textView.setText("文本信息");
                }
            });
        }
    }).start();
}

第二种方式:在handlerMessa中更新UI

向handlerMessage发送一个信息
在handlerMessa中更新UI

private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        textView.setText("----");
    }
};

第三种:runOnUiThread

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        textView.setText("----");
    }
});

第四种:view.post();

textView.post(new Runnable() {
    @Override
    public void run() {
        textView.setText("----");
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值