前言
最近閱讀Android 源代碼,就想着寫個最簡單的Android線程間通訊的方案。這裏主要是還粘貼寫的代碼
正文
循環等待的核心loop函數:
looper.java
public class Looper {
private long ptr;
private Message m;
public Looper(){
ptr = Init();
}
public void postRunabledealy(Message message,long delay){
synchronized (this) {
message.delay = SystemClock.uptimeMillis() + delay;
if (m == null) {
m = message;
} else {
Message tmp = m;
Message priv = m;
while (message.delay > tmp.delay){
if (tmp.next == null){
tmp.next = message;
break;
}
priv = tmp;
tmp = tmp.next;
}
//這是插入情況
if (tmp.next != message){
priv.next = message;
message.next = tmp;
}
}
Intrupt(ptr);
Log.e("addrunable", "postRunabledealy:");
}
}
public void Loop(){
while (true){
Log.e("loop", "Loop: ");
if (m == null){
Wait(ptr, 0);
continue;
}
long now = SystemClock.uptimeMillis();
//需要立即處理,
if (now >= m.delay) {
m.run();
Log.e("loop", "Loop: after run()");
if (null == m.next) {
m = null;
} else {
m = m.next;
}
Log.e("-----------", "Loop: hava remove message");
continue;
}
Wait(ptr, (int) (m.delay-now));
}
}
public native long Init();
public native void Wait(long ptr,int delay) ;
public native void Intrupt(long ptr);
}
這個需要在使用異步線程通訊的線程中初始化
然後當然需要一個消息了:
message.java
package com.baigui.simplehandler;
public abstract class Message implements Runnable {
public Message next;
public long delay;
public Runnable run;
}
最核心的確實cpp層的線程阻塞
調用的接口如下:
extern "C" JNIEXPORT jlong JNICALL
Java_com_baigui_simplehandler_Looper_Init(
JNIEnv *env,
jobject /* this */) {
Looper* nativeMessageQueue = new Looper();
// NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
return reinterpret_cast<jlong>(nativeMessageQueue);
}
extern "C" JNIEXPORT void JNICALL
Java_com_baigui_simplehandler_Looper_Wait(
JNIEnv *env,
jobject, /* this */
jlong ptr,
jint dealay) {
Looper* nativeMessageQueue = reinterpret_cast<Looper*>(ptr);
nativeMessageQueue->wait(dealay);
}
extern "C" JNIEXPORT void JNICALL
Java_com_baigui_simplehandler_Looper_Intrupt(
JNIEnv *env,
jobject, /* this */
jlong ptr) {
Looper* nativeMessageQueue = reinterpret_cast<Looper*>(ptr);
nativeMessageQueue->intrupt();
}
cpp層用來阻塞的關鍵組件:
loop.cpp
Looper::Looper() {
int pendingEventCount;
int pendingEventIndex;
epollFd = epoll_create(1);
inotifyFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
// int result_notify = inotify_add_watch(inotifyFd, argv[1], IN_CREATE | IN_DELETE);
struct epoll_event eventItem;
eventItem.events = EPOLLIN|EPOLLET;
eventItem.data.fd = inotifyFd;
epoll_ctl(epollFd, EPOLL_CTL_ADD, inotifyFd, &eventItem);
}
Looper::~Looper() {
}
void Looper::wait(int delay) {
if (delay == 0) {
int pollResult = epoll_wait(epollFd, pendingEventItems, 16, -1);
} else {
int pollResult = epoll_wait(epollFd, pendingEventItems, 16,delay);
}
__android_log_print(ANDROID_LOG_ERROR, "zj", "%s", "after wait");
}
void Looper::intrupt() {
uint64_t inc = 1;
write(inotifyFd, &inc, sizeof(uint64_t));
}
詳細源碼可移步github倉庫地址
後記
這個主要是pst一下自己寫的代碼部分,