implementation setTimeout&setInterval

This commit is contained in:
pengfei.zhou 2019-07-18 20:11:01 +08:00
parent cfffcf1a61
commit 88265d769d
6 changed files with 188 additions and 8 deletions

View File

@ -10,7 +10,9 @@ import com.github.pengfeizhou.hego.Hego;
import com.github.pengfeizhou.hego.utils.HegoConstant;
import com.github.pengfeizhou.hego.utils.HegoLog;
import com.github.pengfeizhou.hego.utils.HegoSettableFuture;
import com.github.pengfeizhou.hego.utils.HegoTimerExtension;
import com.github.pengfeizhou.hego.utils.HegoUtils;
import com.github.pengfeizhou.jscore.ArchiveException;
import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JavaFunction;
import com.github.pengfeizhou.jscore.JavaValue;
@ -24,9 +26,10 @@ import java.util.ArrayList;
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
public class HegoJSEngine implements Handler.Callback {
public class HegoJSEngine implements Handler.Callback, HegoTimerExtension.TimerCallback {
private final Handler mJSHandler;
private IHegoJSE mHegoJSE;
private HegoTimerExtension mTimerExtension;
public HegoJSEngine() {
HandlerThread handlerThread = new HandlerThread(this.getClass().getSimpleName());
@ -40,6 +43,7 @@ public class HegoJSEngine implements Handler.Callback {
initHugoRuntime();
}
});
mTimerExtension = new HegoTimerExtension(looper, this);
}
@ -65,7 +69,7 @@ public class HegoJSEngine implements Handler.Callback {
} catch (Exception e) {
e.printStackTrace();
}
return new JavaValue();
return null;
}
});
mHegoJSE.injectGlobalJSFunction(HegoConstant.INJECT_REQUIRE, new JavaFunction() {
@ -86,6 +90,31 @@ public class HegoJSEngine implements Handler.Callback {
}
}
});
mHegoJSE.injectGlobalJSFunction(HegoConstant.INJECT_TIMER_SET, new JavaFunction() {
@Override
public JavaValue exec(JSDecoder[] args) {
try {
mTimerExtension.setTimer(
args[0].number().longValue(),
args[1].number().longValue(),
args[2].bool());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
mHegoJSE.injectGlobalJSFunction(HegoConstant.INJECT_TIMER_CLEAR, new JavaFunction() {
@Override
public JavaValue exec(JSDecoder[] args) {
try {
mTimerExtension.clearTimer(args[0].number().longValue());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}
private void initHugoRuntime() {
@ -175,6 +204,8 @@ public class HegoJSEngine implements Handler.Callback {
values.add(new JavaValue((String) arg));
} else if (arg instanceof Integer) {
values.add(new JavaValue((Integer) arg));
} else if (arg instanceof Long) {
values.add(new JavaValue((Long) arg));
} else if (arg instanceof Double) {
values.add(new JavaValue((Double) arg));
} else if (arg instanceof Boolean) {
@ -192,4 +223,9 @@ public class HegoJSEngine implements Handler.Callback {
doOnJSThread(runnable);
return settableFuture;
}
@Override
public void callback(long timerId) {
invokeHegoMethod(HegoConstant.HEGO_TIMER_CALLBACK, timerId);
}
}

View File

@ -8,6 +8,8 @@ package com.github.pengfeizhou.hego.utils;
public class HegoConstant {
public static final String INJECT_LOG = "nativeLog";
public static final String INJECT_REQUIRE = "nativeRequire";
public static final String INJECT_TIMER_SET = "nativeSetTimer";
public static final String INJECT_TIMER_CLEAR = "nativeClearTimer";
public static final String INJECT_BRIDGE = "nativeBridge";
public static final String TEMPLATE_CONTEXT_CREATE = "Reflect.apply(" +
@ -33,4 +35,5 @@ public class HegoConstant {
public static final String GLOBAL_HEGO = "hego";
public static final String HEGO_CONTEXT_RELEASE = "jsReleaseContext";
public static final String HEGO_CONTEXT_INVOKE = "jsCallEntityMethod";
public static final String HEGO_TIMER_CALLBACK = "jsCallbackTimer";
}

View File

@ -0,0 +1,66 @@
package com.github.pengfeizhou.hego.utils;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.util.HashSet;
import java.util.Set;
/**
* @Description: Android
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
public class HegoTimerExtension implements Handler.Callback {
private static final int MSG_TIMER = 0;
private final Handler mTimerHandler;
private final TimerCallback mTimerCallback;
private Set<Long> mDeletedTimerIds = new HashSet<>();
public HegoTimerExtension(Looper looper, TimerCallback timerCallback) {
mTimerHandler = new Handler(looper, this);
mTimerCallback = timerCallback;
}
public void setTimer(long timerId, long time, boolean repeat) {
TimerInfo timerInfo = new TimerInfo();
timerInfo.timerId = timerId;
timerInfo.time = time;
timerInfo.repeat = repeat;
mTimerHandler.sendMessageDelayed(Message.obtain(mTimerHandler, MSG_TIMER, timerInfo), timerInfo.time);
}
public void clearTimer(long timerId) {
mDeletedTimerIds.add(timerId);
}
@Override
public boolean handleMessage(Message msg) {
if (msg.obj instanceof TimerInfo) {
TimerInfo timerInfo = (TimerInfo) msg.obj;
if (mDeletedTimerIds.contains(timerInfo.timerId)) {
mDeletedTimerIds.remove(timerInfo.timerId);
} else {
mTimerCallback.callback(timerInfo.timerId);
if (timerInfo.repeat) {
mTimerHandler.sendMessageDelayed(Message.obtain(mTimerHandler, MSG_TIMER, timerInfo), timerInfo.time);
} else {
mDeletedTimerIds.remove(timerInfo.timerId);
}
}
}
return true;
}
private class TimerInfo {
long timerId;
long time;
boolean repeat;
}
public interface TimerCallback {
void callback(long timerId);
}
}

View File

@ -15,6 +15,19 @@ const layout = new VLayout
layout.space = 10
console.log(layout.viewId)
console.log(layout.toModel())
log('console', Object.getOwnPropertyNames(console))
setTimeout(() => {
log('exec setTimeout')
}, 1000)
const timerId = setInterval(() => {
log('exec setInterval')
}, 1000)
setTimeout(() => {
log('exec cancelTimer')
clearInterval(timerId)
}, 5000)
@Registor(context)
export class MyPage extends Panel {

View File

@ -145,3 +145,44 @@ export function jsCallEntityMethod(contextId: string, methodName: string, args?:
}
}
const global = Function('return this')()
let __timerId__ = 0
const timerCallbacks: Map<number, () => void> = new Map
declare function nativeSetTimer(timerId: number, interval: number, repeat: boolean): void
declare function nativeClearTimer(timerId: number): void
global.setTimeout = (handler: Function, timeout?: number | undefined, ...args: any[]) => {
const id = __timerId__++
timerCallbacks.set(id, () => {
Reflect.apply(handler, undefined, args)
timerCallbacks.delete(id)
})
nativeSetTimer(id, timeout || 0, false)
return id
}
global.setInterval = (handler: Function, timeout?: number | undefined, ...args: any[]) => {
const id = __timerId__++
timerCallbacks.set(id, () => {
Reflect.apply(handler, undefined, args)
})
nativeSetTimer(id, timeout || 0, true)
return id
}
global.clearTimeout = (timerId: number) => {
timerCallbacks.delete(timerId)
nativeClearTimer(timerId)
}
global.clearInterval = (timerId: number) => {
timerCallbacks.delete(timerId)
nativeClearTimer(timerId)
}
export function jsCallbackTimer(timerId: number) {
const timerCallback = timerCallbacks.get(timerId)
if (timerCallback instanceof Function) {
Reflect.apply(timerCallback, undefined, [])
}
}

View File

@ -16,14 +16,35 @@ function toString(message: any) {
}
}
export function log(message: any) {
nativeLog('d', toString(message))
export function log(...args: any) {
let out = ""
for (let i = 0; i < arguments.length; i++) {
if (i > 0) {
out += ','
}
out += toString(arguments[i])
}
nativeLog('d', out)
}
export function loge(message: any) {
nativeLog('e', toString(message))
export function loge(...message: any) {
let out = ""
for (let i = 0; i < arguments.length; i++) {
if (i > 0) {
out += ','
}
out += toString(arguments[i])
}
nativeLog('e', out)
}
export function logw(message: any) {
nativeLog('w', toString(message))
export function logw(...message: any) {
let out = ""
for (let i = 0; i < arguments.length; i++) {
if (i > 0) {
out += ','
}
out += toString(arguments[i])
}
nativeLog('w', out)
}