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.
 

69 lines
1.9 KiB

---
线程的消息队列是怎么创建的?
---
1. 可以在子线程创建 handler 嘛?
2. 主线程的 Looper 和子线程的 Looper 有什么区别?
3. Looper 的 MessageQueue 有什么关系?
4. MessageQueue 是怎么创建的?
NativeMessageQueue:
```c++
jlong MessageQueue_nativeInit(JNIEnv* env, jclass clazz){
NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
return reinterpret_cast<jlong>(nativeMessageQueue);
}
NativeMessageQueue::NativeMessageQueue(){
mLooper = Looper::getForThread();
if(mLooper == NULL){
mLooper = new Looper(false);
Looper::setForThread(mLooper);
}
}
sp<Looper> Looper::getForThread(){
int result = pthread_once(& gTLSOnce, initTLSKey);
return (Looper*)pthread_getspecific(gTLSKey);
}
```
Native Looper:
```c++
Looper::Looper(bool allowNonCallbacks){
mWakeEventFd = eventfd(0, EFD_NONBLOCK);
rebuildEpollLocked();
}
void Looper::rebuildEpollLocked(){
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event));
eventItem.events = EPOLLIN;
eventItem.data.fd = mWakeEventFd;
epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
}
void Looper::wake(){
uint64_t inc = 1;
ssize_t nWrite = write(mWakeEventFd, &inc, sizeof(uint64_t));
}
int Looper::pollOnce(int timeoutMillis, int* outFd, ...){
for(;;){
pollInner(timeoutMillis);
}
}
int Looper::pollInner(int timeoutMillis){
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
int eventCount = epoll_wait(mEpollFd, eventItems, ...);
for(int i=0;i<eventCount;i++){
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
if(fd==mWakeEventFd&&(epollEvents&EPOLLIN)){
awoken();
}
}
}
void Looper::awoken(){
uint64_t counter;
read(mWakeEventFd, &counter, sizeof(uint64_t));
}
```