手写最简handler
Posted 白嫩豆腐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写最简handler相关的知识,希望对你有一定的参考价值。
前言
最近阅读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一下自己写的代码部分,
以上是关于手写最简handler的主要内容,如果未能解决你的问题,请参考以下文章
我的Go+语言初体验——Go+语言构建神经网络实战手写数字识别