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.
116 lines
2.6 KiB
116 lines
2.6 KiB
5 years ago
|
---
|
||
|
线程间消息传递机制
|
||
|
---
|
||
|
|
||
|
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));
|
||
|
}
|
||
|
```
|
||
|
|