change clearMap

This commit is contained in:
pengfei.zhou 2019-07-19 15:03:58 +08:00
parent 3055beb744
commit 0a4bc77b15
13 changed files with 195 additions and 101 deletions

View File

@ -1,9 +1,8 @@
package com.github.pengfeizhou.doric; package com.github.pengfeizhou.doric;
import com.github.pengfeizhou.doric.async.AsyncResult; import com.github.pengfeizhou.doric.async.AsyncResult;
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin; import com.github.pengfeizhou.doric.plugin.DoricNativePlugin;
import com.github.pengfeizhou.doric.extension.DoricPluginInfo; import com.github.pengfeizhou.doric.extension.bridge.DoricPluginInfo;
import com.github.pengfeizhou.doric.async.SettableFuture;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.HashMap; import java.util.HashMap;
@ -27,7 +26,11 @@ public class DoricContext {
} }
public AsyncResult<JSDecoder> callEntity(String methodName, Object... args) { public AsyncResult<JSDecoder> callEntity(String methodName, Object... args) {
return DoricDriver.getInstance().invokeContextMethod(mContextId, methodName, args); return getDriver().invokeContextEntityMethod(mContextId, methodName, args);
}
public DoricDriver getDriver() {
return DoricDriver.getInstance();
} }
@ -36,8 +39,22 @@ public class DoricContext {
} }
public void teardown() { public void teardown() {
DoricDriver.getInstance().destroyContext(mContextId); DoricDriver.getInstance().destroyContext(mContextId).setCallback(new AsyncResult.Callback<Boolean>() {
mPluginMap.clear(); @Override
public void onResult(Boolean result) {
}
@Override
public void onError(Throwable t) {
}
@Override
public void onFinish() {
mPluginMap.clear();
}
});
} }
public DoricNativePlugin obtainPlugin(DoricPluginInfo doricPluginInfo) { public DoricNativePlugin obtainPlugin(DoricPluginInfo doricPluginInfo) {

View File

@ -1,11 +1,20 @@
package com.github.pengfeizhou.doric; package com.github.pengfeizhou.doric;
import android.os.Handler;
import android.os.Looper;
import com.github.pengfeizhou.doric.async.AsyncCall;
import com.github.pengfeizhou.doric.async.AsyncResult; import com.github.pengfeizhou.doric.async.AsyncResult;
import com.github.pengfeizhou.doric.engine.DoricJSEngine; import com.github.pengfeizhou.doric.engine.DoricJSEngine;
import com.github.pengfeizhou.doric.utils.DoricConstant;
import com.github.pengfeizhou.doric.utils.DoricLog;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
@ -17,9 +26,32 @@ public class DoricDriver {
private final DoricJSEngine doricJSEngine; private final DoricJSEngine doricJSEngine;
private final AtomicInteger counter = new AtomicInteger(); private final AtomicInteger counter = new AtomicInteger();
private final Map<String, DoricContext> doricContextMap = new ConcurrentHashMap<>(); private final Map<String, DoricContext> doricContextMap = new ConcurrentHashMap<>();
private final ExecutorService mBridgeExecutor;
private final Handler mUIHandler;
private final Handler mJSHandler;
public AsyncResult<JSDecoder> invokeContextMethod(final String contextId, final String method, final Object... args) { public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) {
return doricJSEngine.invokeContextEntityMethod(contextId, method, args); final Object[] nArgs = new Object[args.length + 2];
nArgs[0] = contextId;
nArgs[1] = method;
if (args.length > 0) {
System.arraycopy(args, 0, nArgs, 2, args.length);
}
return invokeDoricMethod(DoricConstant.DORIC_CONTEXT_INVOKE, nArgs);
}
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
@Override
public JSDecoder call() {
try {
return doricJSEngine.invokeDoricMethod(method, args);
} catch (Exception e) {
DoricLog.e("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage());
return new JSDecoder(null);
}
}
});
} }
private static class Inner { private static class Inner {
@ -28,6 +60,21 @@ public class DoricDriver {
private DoricDriver() { private DoricDriver() {
doricJSEngine = new DoricJSEngine(); doricJSEngine = new DoricJSEngine();
mBridgeExecutor = Executors.newCachedThreadPool();
mUIHandler = new Handler(Looper.getMainLooper());
mJSHandler = doricJSEngine.getJSHandler();
}
public void runOnJS(Runnable runnable) {
mJSHandler.post(runnable);
}
public void runOnUI(Runnable runnable) {
mUIHandler.post(runnable);
}
public void runIndependently(Runnable runnable) {
mBridgeExecutor.execute(runnable);
} }
public static DoricDriver getInstance() { public static DoricDriver getInstance() {
@ -35,26 +82,37 @@ public class DoricDriver {
} }
DoricContext createContext(final String script, final String source) { DoricContext createContext(final String script, final String source) {
String contextId = String.valueOf(counter.incrementAndGet()); final String contextId = String.valueOf(counter.incrementAndGet());
DoricContext doricContext = new DoricContext(contextId); DoricContext doricContext = new DoricContext(contextId);
doricJSEngine.prepareContext(contextId, script, source);
doricContextMap.put(contextId, doricContext); doricContextMap.put(contextId, doricContext);
AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override
public Boolean call() {
try {
doricJSEngine.prepareContext(contextId, script, source);
return true;
} catch (Exception e) {
DoricLog.e("createContext %s error is %s", source, e.getLocalizedMessage());
return false;
}
}
});
return doricContext; return doricContext;
} }
void destroyContext(final String contextId) { AsyncResult<Boolean> destroyContext(final String contextId) {
doricJSEngine.destroyContext(contextId).setCallback(new AsyncResult.Callback<Boolean>() { return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override @Override
public void onResult(Boolean result) { public Boolean call() {
} try {
doricJSEngine.destroyContext(contextId);
@Override doricContextMap.remove(contextId);
public void onError(Throwable t) { return true;
} } catch (Exception e) {
DoricLog.e("destroyContext %s error is %s", contextId, e.getLocalizedMessage());
@Override return false;
public void onFinish() { }
doricContextMap.remove(contextId);
} }
}); });
} }

View File

@ -1,23 +0,0 @@
package com.github.pengfeizhou.doric.bridge;
import com.github.pengfeizhou.doric.DoricContext;
import com.github.pengfeizhou.doric.extension.DoricComponent;
import com.github.pengfeizhou.doric.extension.DoricMethod;
/**
* @Description: Doric
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
@DoricComponent(name = "modal")
public class ModalPlugin extends DoricNativePlugin {
protected ModalPlugin(DoricContext doricContext) {
super(doricContext);
}
@DoricMethod(name = "toast")
public void toast() {
}
}

View File

@ -7,20 +7,16 @@ import android.os.Message;
import android.text.TextUtils; import android.text.TextUtils;
import com.github.pengfeizhou.doric.Doric; import com.github.pengfeizhou.doric.Doric;
import com.github.pengfeizhou.doric.async.AsyncCall; import com.github.pengfeizhou.doric.extension.bridge.DoricBridgeExtension;
import com.github.pengfeizhou.doric.extension.DoricBridgeExtension;
import com.github.pengfeizhou.doric.async.AsyncResult;
import com.github.pengfeizhou.doric.utils.DoricConstant; import com.github.pengfeizhou.doric.utils.DoricConstant;
import com.github.pengfeizhou.doric.utils.DoricLog; import com.github.pengfeizhou.doric.utils.DoricLog;
import com.github.pengfeizhou.doric.async.SettableFuture; import com.github.pengfeizhou.doric.extension.timer.DoricTimerExtension;
import com.github.pengfeizhou.doric.extension.DoricTimerExtension;
import com.github.pengfeizhou.doric.utils.DoricUtils; import com.github.pengfeizhou.doric.utils.DoricUtils;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JavaFunction; import com.github.pengfeizhou.jscore.JavaFunction;
import com.github.pengfeizhou.jscore.JavaValue; import com.github.pengfeizhou.jscore.JavaValue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.Callable;
/** /**
* @Description: Doric * @Description: Doric
@ -49,6 +45,10 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
mDoricBridgeExtension = new DoricBridgeExtension(); mDoricBridgeExtension = new DoricBridgeExtension();
} }
public Handler getJSHandler() {
return mJSHandler;
}
private void initJSExecutor() { private void initJSExecutor() {
mDoricJSE = new DoricJSExecutor(); mDoricJSE = new DoricJSExecutor();
@ -157,34 +157,12 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
mDoricJSE.loadJS(script, "Assets://" + assetName); mDoricJSE.loadJS(script, "Assets://" + assetName);
} }
public AsyncResult<Boolean> prepareContext(final String contextId, final String script, final String source) { public void prepareContext(final String contextId, final String script, final String source) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() { mDoricJSE.loadJS(packageContextScript(contextId, script), "Context://" + source);
@Override
public Boolean call() throws Exception {
try {
mDoricJSE.loadJS(packageContextScript(contextId, script), "Context://" + source);
return true;
} catch (Exception e) {
DoricLog.e("Prepare Context error:%s", e.getLocalizedMessage());
return false;
}
}
});
} }
public AsyncResult<Boolean> destroyContext(final String contextId) { public void destroyContext(final String contextId) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() { mDoricJSE.loadJS(String.format(DoricConstant.TEMPLATE_CONTEXT_DESTROY, contextId), "_Context://" + contextId);
@Override
public Boolean call() throws Exception {
try {
mDoricJSE.loadJS(String.format(DoricConstant.TEMPLATE_CONTEXT_DESTROY, contextId), "_Context://" + contextId);
return true;
} catch (Exception e) {
DoricLog.e("Prepare Context error:%s", e.getLocalizedMessage());
return false;
}
}
});
} }
private String packageContextScript(String contextId, String content) { private String packageContextScript(String contextId, String content) {
@ -195,7 +173,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
return String.format(DoricConstant.TEMPLATE_MODULE, moduleName, content); return String.format(DoricConstant.TEMPLATE_MODULE, moduleName, content);
} }
public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) { public JSDecoder invokeContextEntityMethod(final String contextId, final String method, final Object... args) {
final Object[] nArgs = new Object[args.length + 2]; final Object[] nArgs = new Object[args.length + 2];
nArgs[0] = contextId; nArgs[0] = contextId;
nArgs[1] = method; nArgs[1] = method;
@ -206,18 +184,13 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
} }
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) { public JSDecoder invokeDoricMethod(final String method, final Object... args) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() { ArrayList<JavaValue> values = new ArrayList<>();
@Override for (Object arg : args) {
public JSDecoder call() throws Exception { values.add(DoricUtils.toJavaValue(arg));
ArrayList<JavaValue> values = new ArrayList<>(); }
for (Object arg : args) { return mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
values.add(DoricUtils.toJavaValue(arg)); values.toArray(new JavaValue[values.size()]), true);
}
return mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
values.toArray(new JavaValue[values.size()]), true);
}
});
} }
@Override @Override

View File

@ -1,11 +1,11 @@
package com.github.pengfeizhou.doric.extension; package com.github.pengfeizhou.doric.extension.bridge;
import android.text.TextUtils; import android.text.TextUtils;
import com.github.pengfeizhou.doric.DoricContext; import com.github.pengfeizhou.doric.DoricContext;
import com.github.pengfeizhou.doric.DoricDriver; import com.github.pengfeizhou.doric.DoricDriver;
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin; import com.github.pengfeizhou.doric.plugin.DoricNativePlugin;
import com.github.pengfeizhou.doric.bridge.ModalPlugin; import com.github.pengfeizhou.doric.plugin.ModalPlugin;
import com.github.pengfeizhou.doric.utils.DoricLog; import com.github.pengfeizhou.doric.utils.DoricLog;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JavaValue; import com.github.pengfeizhou.jscore.JavaValue;
@ -50,6 +50,7 @@ public class DoricBridgeExtension {
DoricLog.e("Cannot find plugin method in class:%s,method:%s", module, methodName); DoricLog.e("Cannot find plugin method in class:%s,method:%s", module, methodName);
return new JavaValue(false); return new JavaValue(false);
} }
DoricMethod doricMethod = method.getAnnotation(DoricMethod.class);
Class[] classes = method.getParameterTypes(); Class[] classes = method.getParameterTypes();

View File

@ -1,4 +1,4 @@
package com.github.pengfeizhou.doric.extension; package com.github.pengfeizhou.doric.extension.bridge;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;

View File

@ -1,4 +1,4 @@
package com.github.pengfeizhou.doric.extension; package com.github.pengfeizhou.doric.extension.bridge;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
@ -16,4 +16,12 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface DoricMethod { public @interface DoricMethod {
String name() default ""; String name() default "";
Mode thread() default Mode.INDEPENDENT;
enum Mode {
UI,
JS,
INDEPENDENT,
}
} }

View File

@ -1,9 +1,9 @@
package com.github.pengfeizhou.doric.extension; package com.github.pengfeizhou.doric.extension.bridge;
import android.text.TextUtils; import android.text.TextUtils;
import com.github.pengfeizhou.doric.DoricContext; import com.github.pengfeizhou.doric.DoricContext;
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin; import com.github.pengfeizhou.doric.plugin.DoricNativePlugin;
import com.github.pengfeizhou.doric.utils.DoricLog; import com.github.pengfeizhou.doric.utils.DoricLog;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@ -21,7 +21,6 @@ public class DoricPluginInfo {
private Constructor<? extends DoricNativePlugin> pluginConstructor; private Constructor<? extends DoricNativePlugin> pluginConstructor;
private Map<String, Method> methodMap = new ConcurrentHashMap<>(); private Map<String, Method> methodMap = new ConcurrentHashMap<>();
public boolean stringify = false;
private String name; private String name;
public DoricPluginInfo(Class<? extends DoricNativePlugin> pluginClass) { public DoricPluginInfo(Class<? extends DoricNativePlugin> pluginClass) {

View File

@ -0,0 +1,36 @@
package com.github.pengfeizhou.doric.extension.bridge;
import com.github.pengfeizhou.doric.DoricContext;
import com.github.pengfeizhou.doric.utils.DoricConstant;
import com.github.pengfeizhou.jscore.JavaValue;
/**
* @Description: com.github.pengfeizhou.doric.extension.bridge
* @Author: pengfei.zhou
* @CreateDate: 2019-07-19
*/
public class DoricPromise {
private final DoricContext context;
private final String callbackId;
public DoricPromise(DoricContext context, String callbackId) {
this.context = context;
this.callbackId = callbackId;
}
public void resolve(JavaValue... javaValue) {
context.getDriver().invokeDoricMethod(
DoricConstant.DORIC_BRIDGE_RESOLVE,
context.getContextId(),
callbackId,
javaValue);
}
public void reject(JavaValue... javaValue) {
context.getDriver().invokeDoricMethod(
DoricConstant.DORIC_BRIDGE_REJECT,
context.getContextId(),
callbackId,
javaValue);
}
}

View File

@ -1,4 +1,4 @@
package com.github.pengfeizhou.doric.extension; package com.github.pengfeizhou.doric.extension.timer;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;

View File

@ -1,4 +1,4 @@
package com.github.pengfeizhou.doric.bridge; package com.github.pengfeizhou.doric.plugin;
import com.github.pengfeizhou.doric.DoricContext; import com.github.pengfeizhou.doric.DoricContext;

View File

@ -0,0 +1,24 @@
package com.github.pengfeizhou.doric.plugin;
import com.github.pengfeizhou.doric.DoricContext;
import com.github.pengfeizhou.doric.extension.bridge.DoricComponent;
import com.github.pengfeizhou.doric.extension.bridge.DoricMethod;
import com.github.pengfeizhou.jscore.JSDecoder;
/**
* @Description: Doric
* @Author: pengfei.zhou
* @CreateDate: 2019-07-18
*/
@DoricComponent(name = "modal")
public class ModalPlugin extends DoricNativePlugin {
protected ModalPlugin(DoricContext doricContext) {
super(doricContext);
}
@DoricMethod(name = "toast", thread = DoricMethod.Mode.UI)
public void toast(JSDecoder decoder) {
}
}

View File

@ -11,7 +11,6 @@ public class DoricConstant {
public static final String DORIC_MODULE_LIB = "./index"; public static final String DORIC_MODULE_LIB = "./index";
public static final String INJECT_LOG = "nativeLog"; public static final String INJECT_LOG = "nativeLog";
public static final String INJECT_REQUIRE = "nativeRequire"; public static final String INJECT_REQUIRE = "nativeRequire";
public static final String INJECT_TIMER_SET = "nativeSetTimer"; public static final String INJECT_TIMER_SET = "nativeSetTimer";
@ -42,4 +41,6 @@ public class DoricConstant {
public static final String DORIC_CONTEXT_RELEASE = "jsReleaseContext"; public static final String DORIC_CONTEXT_RELEASE = "jsReleaseContext";
public static final String DORIC_CONTEXT_INVOKE = "jsCallEntityMethod"; public static final String DORIC_CONTEXT_INVOKE = "jsCallEntityMethod";
public static final String DORIC_TIMER_CALLBACK = "jsCallbackTimer"; public static final String DORIC_TIMER_CALLBACK = "jsCallbackTimer";
public static final String DORIC_BRIDGE_RESOLVE = "jsCallResolve";
public static final String DORIC_BRIDGE_REJECT = "jsCallReject";
} }