add async package
This commit is contained in:
parent
920aab1035
commit
3055beb744
@ -1,8 +1,9 @@
|
|||||||
package com.github.pengfeizhou.doric;
|
package com.github.pengfeizhou.doric;
|
||||||
|
|
||||||
|
import com.github.pengfeizhou.doric.async.AsyncResult;
|
||||||
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin;
|
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin;
|
||||||
import com.github.pengfeizhou.doric.extension.DoricPluginInfo;
|
import com.github.pengfeizhou.doric.extension.DoricPluginInfo;
|
||||||
import com.github.pengfeizhou.doric.utils.DoricSettableFuture;
|
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;
|
||||||
@ -25,7 +26,7 @@ public class DoricContext {
|
|||||||
return DoricDriver.getInstance().createContext(script, alias);
|
return DoricDriver.getInstance().createContext(script, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DoricSettableFuture<JSDecoder> callEntity(String methodName, Object... args) {
|
public AsyncResult<JSDecoder> callEntity(String methodName, Object... args) {
|
||||||
return DoricDriver.getInstance().invokeContextMethod(mContextId, methodName, args);
|
return DoricDriver.getInstance().invokeContextMethod(mContextId, methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.github.pengfeizhou.doric;
|
package com.github.pengfeizhou.doric;
|
||||||
|
|
||||||
|
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.DoricSettableFuture;
|
|
||||||
import com.github.pengfeizhou.jscore.JSDecoder;
|
import com.github.pengfeizhou.jscore.JSDecoder;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -18,7 +18,7 @@ public class DoricDriver {
|
|||||||
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<>();
|
||||||
|
|
||||||
public DoricSettableFuture<JSDecoder> invokeContextMethod(final String contextId, final String method, final Object... args) {
|
public AsyncResult<JSDecoder> invokeContextMethod(final String contextId, final String method, final Object... args) {
|
||||||
return doricJSEngine.invokeContextEntityMethod(contextId, method, args);
|
return doricJSEngine.invokeContextEntityMethod(contextId, method, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,15 +36,27 @@ 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());
|
String contextId = String.valueOf(counter.incrementAndGet());
|
||||||
doricJSEngine.prepareContext(contextId, script, source);
|
|
||||||
DoricContext doricContext = new DoricContext(contextId);
|
DoricContext doricContext = new DoricContext(contextId);
|
||||||
|
doricJSEngine.prepareContext(contextId, script, source);
|
||||||
doricContextMap.put(contextId, doricContext);
|
doricContextMap.put(contextId, doricContext);
|
||||||
return doricContext;
|
return doricContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyContext(String contextId) {
|
void destroyContext(final String contextId) {
|
||||||
|
doricJSEngine.destroyContext(contextId).setCallback(new AsyncResult.Callback<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public void onResult(Boolean result) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
doricContextMap.remove(contextId);
|
doricContextMap.remove(contextId);
|
||||||
doricJSEngine.destroyContext(contextId);
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public DoricContext getContext(String contextId) {
|
public DoricContext getContext(String contextId) {
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.github.pengfeizhou.doric.async;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: com.github.pengfeizhou.doric.async
|
||||||
|
* @Author: pengfei.zhou
|
||||||
|
* @CreateDate: 2019-07-19
|
||||||
|
*/
|
||||||
|
public class AsyncCall {
|
||||||
|
|
||||||
|
public static <T> AsyncResult<T> ensureRunInHandler(Handler handler, final Callable<T> callable) {
|
||||||
|
final AsyncResult<T> asyncResult = new AsyncResult<>();
|
||||||
|
if (Looper.myLooper() == handler.getLooper()) {
|
||||||
|
try {
|
||||||
|
asyncResult.setResult(callable.call());
|
||||||
|
} catch (Exception e) {
|
||||||
|
asyncResult.setError(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
handler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
asyncResult.setResult(callable.call());
|
||||||
|
} catch (Exception e) {
|
||||||
|
asyncResult.setError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return asyncResult;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.github.pengfeizhou.doric.async;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: com.github.pengfeizhou.doric.async
|
||||||
|
* @Author: pengfei.zhou
|
||||||
|
* @CreateDate: 2019-07-19
|
||||||
|
*/
|
||||||
|
public class AsyncResult<R> {
|
||||||
|
private static Object EMPTY = new Object();
|
||||||
|
private Object result = EMPTY;
|
||||||
|
|
||||||
|
private Callback<R> callback = null;
|
||||||
|
|
||||||
|
public void setResult(R result) {
|
||||||
|
this.result = result;
|
||||||
|
if (this.callback != null) {
|
||||||
|
this.callback.onResult(result);
|
||||||
|
this.callback.onFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(Throwable result) {
|
||||||
|
this.result = result;
|
||||||
|
if (this.callback != null) {
|
||||||
|
this.callback.onError(result);
|
||||||
|
this.callback.onFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCallback(Callback<R> callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
if (result instanceof Throwable) {
|
||||||
|
this.callback.onError((Throwable) result);
|
||||||
|
this.callback.onFinish();
|
||||||
|
} else if (result != EMPTY) {
|
||||||
|
this.callback.onResult((R) result);
|
||||||
|
this.callback.onFinish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SettableFuture<R> synchronous() {
|
||||||
|
final SettableFuture<R> settableFuture = new SettableFuture<>();
|
||||||
|
|
||||||
|
setCallback(new Callback<R>() {
|
||||||
|
@Override
|
||||||
|
public void onResult(R result) {
|
||||||
|
settableFuture.set(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
settableFuture.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return settableFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Callback<R> {
|
||||||
|
void onResult(R result);
|
||||||
|
|
||||||
|
void onError(Throwable t);
|
||||||
|
|
||||||
|
void onFinish();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.github.pengfeizhou.doric.utils;
|
package com.github.pengfeizhou.doric.async;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Description: Doric
|
* @Description: com.github.pengfeizhou.doric.async
|
||||||
* @Author: pengfei.zhou
|
* @Author: pengfei.zhou
|
||||||
* @CreateDate: 2019-07-18
|
* @CreateDate: 2019-07-18
|
||||||
*/
|
*/
|
||||||
@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* A super simple Future-like class that can safely notify another Thread when a value is ready.
|
* A super simple Future-like class that can safely notify another Thread when a value is ready.
|
||||||
* Does not support setting errors or canceling.
|
* Does not support setting errors or canceling.
|
||||||
*/
|
*/
|
||||||
public class DoricSettableFuture<T> {
|
public class SettableFuture<T> {
|
||||||
|
|
||||||
private final CountDownLatch mReadyLatch = new CountDownLatch(1);
|
private final CountDownLatch mReadyLatch = new CountDownLatch(1);
|
||||||
private volatile
|
private volatile
|
@ -7,10 +7,12 @@ 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.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.utils.DoricSettableFuture;
|
import com.github.pengfeizhou.doric.async.SettableFuture;
|
||||||
import com.github.pengfeizhou.doric.extension.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;
|
||||||
@ -18,6 +20,7 @@ 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
|
||||||
@ -154,32 +157,34 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
|
|||||||
mDoricJSE.loadJS(script, "Assets://" + assetName);
|
mDoricJSE.loadJS(script, "Assets://" + assetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareContext(final String contextId, final String script, final String source) {
|
public AsyncResult<Boolean> prepareContext(final String contextId, final String script, final String source) {
|
||||||
Runnable runnable = new Runnable() {
|
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Boolean call() throws Exception {
|
||||||
|
try {
|
||||||
mDoricJSE.loadJS(packageContextScript(contextId, script), "Context://" + source);
|
mDoricJSE.loadJS(packageContextScript(contextId, script), "Context://" + source);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
DoricLog.e("Prepare Context error:%s", e.getLocalizedMessage());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
doOnJSThread(runnable);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doOnJSThread(Runnable runnable) {
|
public AsyncResult<Boolean> destroyContext(final String contextId) {
|
||||||
if (isJSThread()) {
|
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
||||||
runnable.run();
|
|
||||||
} else {
|
|
||||||
mJSHandler.post(runnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroyContext(final String contextId) {
|
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Boolean call() throws Exception {
|
||||||
|
try {
|
||||||
mDoricJSE.loadJS(String.format(DoricConstant.TEMPLATE_CONTEXT_DESTROY, contextId), "_Context://" + contextId);
|
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;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
doOnJSThread(runnable);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String packageContextScript(String contextId, String content) {
|
private String packageContextScript(String contextId, String content) {
|
||||||
@ -190,11 +195,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 boolean isJSThread() {
|
public AsyncResult<JSDecoder> invokeContextEntityMethod(final String contextId, final String method, final Object... args) {
|
||||||
return Looper.myLooper() == mJSHandler.getLooper();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DoricSettableFuture<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;
|
||||||
@ -205,21 +206,18 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DoricSettableFuture<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
|
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
|
||||||
final DoricSettableFuture<JSDecoder> settableFuture = new DoricSettableFuture<>();
|
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public JSDecoder call() throws Exception {
|
||||||
ArrayList<JavaValue> values = new ArrayList<>();
|
ArrayList<JavaValue> values = new ArrayList<>();
|
||||||
for (Object arg : args) {
|
for (Object arg : args) {
|
||||||
values.add(DoricUtils.toJavaValue(arg));
|
values.add(DoricUtils.toJavaValue(arg));
|
||||||
}
|
}
|
||||||
settableFuture.set(mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
|
return mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
|
||||||
values.toArray(new JavaValue[values.size()]), true));
|
values.toArray(new JavaValue[values.size()]), true);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
doOnJSThread(runnable);
|
|
||||||
return settableFuture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.github.pengfeizhou.doric.utils;
|
package com.github.pengfeizhou.doric.utils;
|
||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
import com.github.pengfeizhou.doric.Doric;
|
import com.github.pengfeizhou.doric.Doric;
|
||||||
import com.github.pengfeizhou.jscore.JavaValue;
|
import com.github.pengfeizhou.jscore.JavaValue;
|
||||||
@ -60,4 +62,5 @@ public class DoricUtils {
|
|||||||
return new JavaValue(String.valueOf(arg));
|
return new JavaValue(String.valueOf(arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user