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.engine.DoricJSEngine;
import com.github.penfeizhou.doric.utils.DoricConstant; import com.github.penfeizhou.doric.utils.DoricConstant;
import com.github.penfeizhou.doric.utils.DoricLog; import com.github.penfeizhou.doric.utils.DoricLog;
import com.github.penfeizhou.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@ -25,6 +26,7 @@ public class DoricDriver implements IDoricDriver {
private final Handler mUIHandler; private final Handler mUIHandler;
private final Handler mJSHandler; private final Handler mJSHandler;
@Override
public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) { public AsyncResult<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;
@ -35,6 +37,7 @@ public class DoricDriver implements IDoricDriver {
return invokeDoricMethod(DoricConstant.DORIC_CONTEXT_INVOKE, nArgs); return invokeDoricMethod(DoricConstant.DORIC_CONTEXT_INVOKE, nArgs);
} }
@Override
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) { public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() { return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
@Override @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 class Inner {
private static final DoricDriver sInstance = new DoricDriver(); private static final DoricDriver sInstance = new DoricDriver();
} }
@ -60,22 +77,12 @@ public class DoricDriver implements IDoricDriver {
mJSHandler = doricJSEngine.getJSHandler(); 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() {
return Inner.sInstance; return Inner.sInstance;
} }
@Override
public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) { public AsyncResult<Boolean> createContext(final String contextId, final String script, final String source) {
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() { return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
@Override @Override

View File

@ -2,8 +2,11 @@ package com.github.penfeizhou.doric;
import com.github.penfeizhou.doric.async.AsyncResult; import com.github.penfeizhou.doric.async.AsyncResult;
import com.github.penfeizhou.doric.utils.ThreadMode;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import java.util.concurrent.Callable;
/** /**
* @Description: com.github.pengfeizhou.doric * @Description: com.github.pengfeizhou.doric
* @Author: pengfei.zhou * @Author: pengfei.zhou
@ -14,11 +17,7 @@ public interface IDoricDriver {
AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args); AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args);
void runOnJS(Runnable runnable); <T> AsyncResult<T> asyncCall(Callable<T> callable, ThreadMode threadMode);
void runOnUI(Runnable runnable);
void runIndependently(Runnable runnable);
AsyncResult<Boolean> createContext(final String contextId, final String script, final String source); 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 android.os.Looper;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
/** /**
* @Description: com.github.pengfeizhou.doric.async * @Description: com.github.pengfeizhou.doric.async
@ -34,4 +35,19 @@ public class AsyncCall {
} }
return asyncResult; 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) { public void setCallback(Callback<R> callback) {
this.callback = callback; this.callback = callback;
if (result instanceof Throwable) { if (result instanceof Throwable) {

View File

@ -3,6 +3,8 @@ package com.github.penfeizhou.doric.extension.bridge;
import android.text.TextUtils; import android.text.TextUtils;
import com.github.penfeizhou.doric.DoricContext; 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.DoricNativePlugin;
import com.github.penfeizhou.doric.plugin.ModalPlugin; import com.github.penfeizhou.doric.plugin.ModalPlugin;
import com.github.penfeizhou.doric.DoricContextManager; import com.github.penfeizhou.doric.DoricContextManager;
@ -14,6 +16,7 @@ import com.github.pengfeizhou.jscore.JavaValue;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable;
/** /**
* @Description: Doric * @Description: Doric
@ -34,25 +37,27 @@ public class DoricBridgeExtension {
} }
} }
public JavaValue callNative(String contextId, String module, String methodName, String callbackId, JSDecoder jsDecoder) { public JavaValue callNative(String contextId, String module, String methodName, final String callbackId, final JSDecoder jsDecoder) {
DoricContext context = DoricContextManager.getContext(contextId); final DoricContext context = DoricContextManager.getContext(contextId);
DoricPluginInfo pluginInfo = pluginInfoMap.get(module); DoricPluginInfo pluginInfo = pluginInfoMap.get(module);
if (pluginInfo == null) { if (pluginInfo == null) {
DoricLog.e("Cannot find plugin class:%s", module); DoricLog.e("Cannot find plugin class:%s", module);
return new JavaValue(false); return new JavaValue(false);
} }
DoricNativePlugin doricNativePlugin = context.obtainPlugin(pluginInfo); final DoricNativePlugin doricNativePlugin = context.obtainPlugin(pluginInfo);
if (doricNativePlugin == null) { if (doricNativePlugin == null) {
DoricLog.e("Cannot obtain plugin instance:%s,method:%", module); DoricLog.e("Cannot obtain plugin instance:%s,method:%", module);
return new JavaValue(false); return new JavaValue(false);
} }
Method method = pluginInfo.getMethod(methodName); final Method method = pluginInfo.getMethod(methodName);
if (method == null) { if (method == null) {
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); DoricMethod doricMethod = method.getAnnotation(DoricMethod.class);
try { Callable<JavaValue> callable = new Callable<JavaValue>() {
@Override
public JavaValue call() throws Exception {
Class[] classes = method.getParameterTypes(); Class[] classes = method.getParameterTypes();
Object ret; Object ret;
if (classes.length == 0) { if (classes.length == 0) {
@ -65,10 +70,13 @@ public class DoricBridgeExtension {
createParam(context, classes[1], 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) { private Object createParam(DoricContext context, Class clz, String callbackId, JSDecoder jsDecoder) {

View File

@ -1,5 +1,7 @@
package com.github.penfeizhou.doric.extension.bridge; package com.github.penfeizhou.doric.extension.bridge;
import com.github.penfeizhou.doric.utils.ThreadMode;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -17,11 +19,5 @@ import java.lang.annotation.Target;
public @interface DoricMethod { public @interface DoricMethod {
String name() default ""; String name() default "";
Mode thread() default Mode.INDEPENDENT; ThreadMode thread() default ThreadMode.INDEPENDENT;
enum Mode {
UI,
JS,
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.DoricComponent;
import com.github.penfeizhou.doric.extension.bridge.DoricMethod; import com.github.penfeizhou.doric.extension.bridge.DoricMethod;
import com.github.penfeizhou.doric.extension.bridge.DoricPromise; 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.ArchiveException;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
@ -21,7 +22,7 @@ public class ModalPlugin extends DoricNativePlugin {
super(doricContext); super(doricContext);
} }
@DoricMethod(name = "toast", thread = DoricMethod.Mode.UI) @DoricMethod(name = "toast", thread = ThreadMode.UI)
public void toast(JSDecoder decoder, DoricPromise promise) { public void toast(JSDecoder decoder, DoricPromise promise) {
try { try {
Toast.makeText(getDoricContext().getContext(), decoder.string(), Toast.LENGTH_SHORT).show(); 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,
}