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.
 

1.9 KiB

线程的消息队列是怎么创建的?
  1. 可以在子线程创建 handler 嘛?
  2. 主线程的 Looper 和子线程的 Looper 有什么区别?
  3. Looper 的 MessageQueue 有什么关系?
  4. MessageQueue 是怎么创建的?

NativeMessageQueue:

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:

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));
}