最近阅读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(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一下自己写的代码部分,