feat:config thread

This commit is contained in:
pengfei.zhou 2019-07-20 10:35:14 +08:00
parent 65fcd5c1fc
commit bc05a1b8e4
8 changed files with 90 additions and 43 deletions

View File

@ -8,6 +8,7 @@ import com.github.penfeizhou.doric.async.AsyncResult;
import com.github.penfeizhou.doric.engine.DoricJSEngine;
import com.github.penfeizhou.doric.utils.DoricConstant;
import com.github.penfeizhou.doric.utils.DoricLog;
import com.github.penfeizhou.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.concurrent.Callable;
@ -25,6 +26,7 @@ public class DoricDriver implements IDoricDriver {
private final Handler mUIHandler;
private final Handler mJSHandler;
@Override
public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) {
final Object[] nArgs = new Object[args.length + 2];
nArgs[0] = contextId;
@ -35,6 +37,7 @@ public class DoricDriver implements IDoricDriver {
return invokeDoricMethod(DoricConstant.DORIC_CONTEXT_INVOKE, nArgs);
}
@Override
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
@Override
@ -49,6 +52,20 @@ public class DoricDriver implements IDoricDriver {
});
}
@Override
public <T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode) {
switch (threadMode) {
case JS:
return AsyncCall.ensureRunInHandler(mJSHandler, callable);
case UI:
return AsyncCall.ensureRunInHandler(mUIHandler, callable);
case INDEPENDENT:
default:
return AsyncCall.ensureRunIExecutor(mBridgeExecutor, callable);
}
}
private static class Inner {
private static final DoricDriver sInstance = new DoricDriver();
}
@ -60,22 +77,12 @@ public class DoricDriver implements IDoricDriver {
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() {
return Inner.sInstance;
}
@Override
public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override

View File

@ -2,8 +2,11 @@ package com.github.penfeizhou.doric;
import com.github.penfeizhou.doric.async.AsyncResult;
import com.github.penfeizhou.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.concurrent.Callable;
/**
* @Description: com.github.pengfeizhou.doric
* @Author: pengfei.zhou
@ -14,11 +17,7 @@ public interface IDoricDriver {
AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args);
void runOnJS(Runnable runnable);
void runOnUI(Runnable runnable);
void runIndependently(Runnable runnable);
<T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode);
AsyncResult<Boolean> createContext(final String contextId, final String script, final String source);

View File

@ -4,6 +4,7 @@ import android.os.Handler;
import android.os.Looper;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
/**
* @Description: com.github.pengfeizhou.doric.async
@ -34,4 +35,19 @@ public class AsyncCall {
}
return asyncResult;
}
public static <T> AsyncResult<T> ensureRunIExecutor(ExecutorService executorService, final Callable<T> callable) {
final AsyncResult<T> asyncResult = new AsyncResult<>();
executorService.execute(new Runnable() {
@Override
public void run() {
try {
asyncResult.setResult(callable.call());
} catch (Exception e) {
asyncResult.setError(e);
}
}
});
return asyncResult;
}
}

View File

@ -27,6 +27,14 @@ public class AsyncResult<R> {
}
}
public boolean hasResult() {
return result != EMPTY;
}
public R getResult() {
return (R) result;
}
public void setCallback(Callback<R> callback) {
this.callback = callback;
if (result instanceof Throwable) {

View File

@ -3,6 +3,8 @@ package com.github.penfeizhou.doric.extension.bridge;
import android.text.TextUtils;
import com.github.penfeizhou.doric.DoricContext;
import com.github.penfeizhou.doric.async.AsyncCall;
import com.github.penfeizhou.doric.async.AsyncResult;
import com.github.penfeizhou.doric.plugin.DoricNativePlugin;
import com.github.penfeizhou.doric.plugin.ModalPlugin;
import com.github.penfeizhou.doric.DoricContextManager;
@ -14,6 +16,7 @@ import com.github.pengfeizhou.jscore.JavaValue;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* @Description: Doric
@ -34,41 +37,46 @@ public class DoricBridgeExtension {
}
}
public JavaValue callNative(String contextId, String module, String methodName, String callbackId, JSDecoder jsDecoder) {
DoricContext context = DoricContextManager.getContext(contextId);
public JavaValue callNative(String contextId, String module, String methodName, final String callbackId, final JSDecoder jsDecoder) {
final DoricContext context = DoricContextManager.getContext(contextId);
DoricPluginInfo pluginInfo = pluginInfoMap.get(module);
if (pluginInfo == null) {
DoricLog.e("Cannot find plugin class:%s", module);
return new JavaValue(false);
}
DoricNativePlugin doricNativePlugin = context.obtainPlugin(pluginInfo);
final DoricNativePlugin doricNativePlugin = context.obtainPlugin(pluginInfo);
if (doricNativePlugin == null) {
DoricLog.e("Cannot obtain plugin instance:%s,method:%", module);
return new JavaValue(false);
}
Method method = pluginInfo.getMethod(methodName);
final Method method = pluginInfo.getMethod(methodName);
if (method == null) {
DoricLog.e("Cannot find plugin method in class:%s,method:%s", module, methodName);
return new JavaValue(false);
}
DoricMethod doricMethod = method.getAnnotation(DoricMethod.class);
try {
Class[] classes = method.getParameterTypes();
Object ret;
if (classes.length == 0) {
ret = method.invoke(doricNativePlugin);
} else if (classes.length == 1) {
ret = method.invoke(doricNativePlugin, createParam(context, classes[0], callbackId, jsDecoder));
} else {
ret = method.invoke(doricNativePlugin,
createParam(context, classes[0], callbackId, jsDecoder),
createParam(context, classes[1], callbackId, jsDecoder));
Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override
public JavaValue call() throws Exception {
Class[] classes = method.getParameterTypes();
Object ret;
if (classes.length == 0) {
ret = method.invoke(doricNativePlugin);
} else if (classes.length == 1) {
ret = method.invoke(doricNativePlugin, createParam(context, classes[0], callbackId, jsDecoder));
} else {
ret = method.invoke(doricNativePlugin,
createParam(context, classes[0], callbackId, jsDecoder),
createParam(context, classes[1], callbackId, jsDecoder));
}
return DoricUtils.toJavaValue(ret);
}
return DoricUtils.toJavaValue(ret);
} catch (Exception e) {
DoricLog.e("callNative error:%s", e.getLocalizedMessage());
return new JavaValue(false);
};
AsyncResult<JavaValue> asyncResult = context.getDriver().asyncCall(callable, doricMethod.thread());
if (asyncResult.hasResult()) {
return asyncResult.getResult();
}
return new JavaValue(true);
}
private Object createParam(DoricContext context, Class clz, String callbackId, JSDecoder jsDecoder) {

View File

@ -1,5 +1,7 @@
package com.github.penfeizhou.doric.extension.bridge;
import com.github.penfeizhou.doric.utils.ThreadMode;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -17,11 +19,5 @@ import java.lang.annotation.Target;
public @interface DoricMethod {
String name() default "";
Mode thread() default Mode.INDEPENDENT;
enum Mode {
UI,
JS,
INDEPENDENT,
}
ThreadMode thread() default ThreadMode.INDEPENDENT;
}

View File

@ -6,6 +6,7 @@ import com.github.penfeizhou.doric.DoricContext;
import com.github.penfeizhou.doric.extension.bridge.DoricComponent;
import com.github.penfeizhou.doric.extension.bridge.DoricMethod;
import com.github.penfeizhou.doric.extension.bridge.DoricPromise;
import com.github.penfeizhou.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.ArchiveException;
import com.github.pengfeizhou.jscore.JSDecoder;
@ -21,7 +22,7 @@ public class ModalPlugin extends DoricNativePlugin {
super(doricContext);
}
@DoricMethod(name = "toast", thread = DoricMethod.Mode.UI)
@DoricMethod(name = "toast", thread = ThreadMode.UI)
public void toast(JSDecoder decoder, DoricPromise promise) {
try {
Toast.makeText(getDoricContext().getContext(), decoder.string(), Toast.LENGTH_SHORT).show();

View File

@ -0,0 +1,12 @@
package com.github.penfeizhou.doric.utils;
/**
* @Description: com.github.penfeizhou.doric.utils
* @Author: pengfei.zhou
* @CreateDate: 2019-07-20
*/
public enum ThreadMode {
UI,
JS,
INDEPENDENT,
}