You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
android-notes/blogs/Android/Framework/Interview/线程通信相关/线程间消息传递机制.md

115 lines
2.6 KiB

---
线程间消息传递机制
---
1. 消息循环过程是怎样的?
2. 消息是怎么发送的?
3. 消息是怎么处理的?
```java
// Looper#loop
public static void loop(){
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for(;;){
Message msg = queue.next();
if(msg == null){
return;
}
msg.target.dispatchMessage(msg);
msg.recycleUnchecked();
}
}
public void dispatchMessage(Message msg){
if(msg.callback != null){
handleCallback(msg);
}else{
if(mCallback!=null){
if(mCallback.handleMessage(msg)){
return;
}
}
handleMessage(msg);
}
}
Message next(){
int nextPollTimeoutMillis = 0;
for(;;){
nativePollOnce(ptr, nextPollTimeoutMillis);
Message msg = mMessages;
mMessages = msg.next;
msg.next = null;
msg.markInUse();
return msg;
}
}
```
```c++
void MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, jlong ptr, jint timeoutMillis){
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis){
mLooper->pollOnce(timeoutMillis);
}
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, ...){
int result = 0;
for(;;){
if(result!=0){
return result;
}
result = pollInner(timeoutMillis);
}
}
int Looper::pollInner(int timeoutMillis){
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, ..., timeoutMillis);
for(int i=0;i<eventCount;i++){
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if(fd == mWakeEventFd){
if(epollEvents & EPOLLIN){
awoken();
}
}
}
}
```
```java
Message next(){
int nextPollTimeoutMillis = 0;
for(;;){
nativePollOnce(ptr, nextPollTimeoutMillis);
Message msg = mMessage;
mMessage = msg.next;
msg.next = null;
msg.markInUse();
return msg;
}
}
```
插入消息
```java
boolean enqueueMessage(Message msg, long when) {
nativeWake(mPrt);
return true;
}
```
```c++
void MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr){
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->wake();
}
void Looper::wake(){
uint64_t inc = 1;
write(mWakeEventFd, &inc, sizeof(uint64_t));
}
```