用过android的同学对于handler应该都很了解,用起来比较方便。这里用rust设计了一个简单的rust。
1.处理接口
pub trait ProcessMessage {
fn handleMessage(&self,msg:Message);
}
2.Message结构体
pub struct Message {
pub what:u32,
pub arg1:i32,
pub arg2:i32,
pub next_time:u64,
pub next:Option<Rc<RefCell<Message>>>, //1
pub target:Option<Arc<Box<dyn ProcessMessage>>>//2
}
1.指向下一个message,整个消息队列采用链表结构,使用option主要是为了确认是否还有message
2.target是一个回调实现,每个message都需要带有target,这样message就能由指定的handler处理了。
关键函数
impl Message {
....
fn execute(&self) {
match &self.target {
None=> {},
Some(handler) => {
handler.handleMessage(
Message{
what:self.what,
arg1:self.arg1,
arg2:self.arg2,
next_time:self.next_time,
next:None,
target:None
}
)
} //1
}
}
}
1.message处理的时候调用了ProcessMessage,这里主要考虑到使用的方便(不要再用什么unwrap),所以传出去的数据重新构造了一个新数据,性能上会有损耗
3.消息队列
pub struct MessageQueue {
head:Mutex<Message>,//1
cond:Condvar//2
}
1.消息队列头,为了减少option,这里规定了第一个消息一直不使用,所有消息从head的next开始排队
2.cond:如果没有消息,或者消息需要延迟发送,则使用这个做等待处理。每次有新消息加入的时候,重新针对消息队列排序,然后cond.notify一下,唤醒等待线程
4.Looper
struct Looper {
queue:Arc<RefCell<MessageQueue>>,
}
Looper主要就是一个queue,
关键函数:
fn loop_self(&self) {
loop {
println!("loop self start");
let msg = self.queue.clone().try_borrow_mut().unwrap().dequeue_message();//1
println!("loop self trace1");
match msg {
None=>{},
Some(m) => {
let _msg = m.clone();
_msg.try_borrow_mut().unwrap().execute()