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
69 lines
1.9 KiB
5 years ago
|
---
|
||
|
线程的消息队列是怎么创建的?
|
||
|
---
|
||
|
|
||
|
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));
|
||
|
}
|
||
|
```
|