add async package
This commit is contained in:
parent
920aab1035
commit
3055beb744
@ -1,8 +1,9 @@
|
||||
package com.github.pengfeizhou.doric;
|
||||
|
||||
import com.github.pengfeizhou.doric.async.AsyncResult;
|
||||
import com.github.pengfeizhou.doric.bridge.DoricNativePlugin;
|
||||
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 java.util.HashMap;
|
||||
@ -25,7 +26,7 @@ public class DoricContext {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.github.pengfeizhou.doric;
|
||||
|
||||
import com.github.pengfeizhou.doric.async.AsyncResult;
|
||||
import com.github.pengfeizhou.doric.engine.DoricJSEngine;
|
||||
import com.github.pengfeizhou.doric.utils.DoricSettableFuture;
|
||||
import com.github.pengfeizhou.jscore.JSDecoder;
|
||||
|
||||
import java.util.Map;
|
||||
@ -18,7 +18,7 @@ public class DoricDriver {
|
||||
private final AtomicInteger counter = new AtomicInteger();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -36,15 +36,27 @@ public class DoricDriver {
|
||||
|
||||
DoricContext createContext(final String script, final String source) {
|
||||
String contextId = String.valueOf(counter.incrementAndGet());
|
||||
doricJSEngine.prepareContext(contextId, script, source);
|
||||
DoricContext doricContext = new DoricContext(contextId);
|
||||
doricJSEngine.prepareContext(contextId, script, source);
|
||||
doricContextMap.put(contextId, doricContext);
|
||||
return doricContext;
|
||||
}
|
||||
|
||||
void destroyContext(String contextId) {
|
||||
doricContextMap.remove(contextId);
|
||||
doricJSEngine.destroyContext(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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
* @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.
|
||||
* Does not support setting errors or canceling.
|
||||
*/
|
||||
public class DoricSettableFuture<T> {
|
||||
public class SettableFuture<T> {
|
||||
|
||||
private final CountDownLatch mReadyLatch = new CountDownLatch(1);
|
||||
private volatile
|
@ -7,10 +7,12 @@ import android.os.Message;
|
||||
import android.text.TextUtils;
|
||||
|
||||
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.async.AsyncResult;
|
||||
import com.github.pengfeizhou.doric.utils.DoricConstant;
|
||||
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.utils.DoricUtils;
|
||||
import com.github.pengfeizhou.jscore.JSDecoder;
|
||||
@ -18,6 +20,7 @@ import com.github.pengfeizhou.jscore.JavaFunction;
|
||||
import com.github.pengfeizhou.jscore.JavaValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @Description: Doric
|
||||
@ -154,32 +157,34 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time
|
||||
mDoricJSE.loadJS(script, "Assets://" + assetName);
|
||||
}
|
||||
|
||||
public void prepareContext(final String contextId, final String script, final String source) {
|
||||
Runnable runnable = new Runnable() {
|
||||
public AsyncResult<Boolean> prepareContext(final String contextId, final String script, final String source) {
|
||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDoricJSE.loadJS(packageContextScript(contextId, script), "Context://" + source);
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
doOnJSThread(runnable);
|
||||
});
|
||||
}
|
||||
|
||||
public void doOnJSThread(Runnable runnable) {
|
||||
if (isJSThread()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
mJSHandler.post(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroyContext(final String contextId) {
|
||||
Runnable runnable = new Runnable() {
|
||||
public AsyncResult<Boolean> destroyContext(final String contextId) {
|
||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<Boolean>() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDoricJSE.loadJS(String.format(DoricConstant.TEMPLATE_CONTEXT_DESTROY, contextId), "_Context://" + contextId);
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
doOnJSThread(runnable);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public boolean isJSThread() {
|
||||
return Looper.myLooper() == mJSHandler.getLooper();
|
||||
}
|
||||
|
||||
public DoricSettableFuture<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];
|
||||
nArgs[0] = contextId;
|
||||
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) {
|
||||
final DoricSettableFuture<JSDecoder> settableFuture = new DoricSettableFuture<>();
|
||||
Runnable runnable = new Runnable() {
|
||||
public AsyncResult<JSDecoder> invokeDoricMethod(final String method, final Object... args) {
|
||||
return AsyncCall.ensureRunInHandler(mJSHandler, new Callable<JSDecoder>() {
|
||||
@Override
|
||||
public void run() {
|
||||
public JSDecoder call() throws Exception {
|
||||
ArrayList<JavaValue> values = new ArrayList<>();
|
||||
for (Object arg : args) {
|
||||
values.add(DoricUtils.toJavaValue(arg));
|
||||
}
|
||||
settableFuture.set(mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
|
||||
values.toArray(new JavaValue[values.size()]), true));
|
||||
return mDoricJSE.invokeMethod(DoricConstant.GLOBAL_DORIC, method,
|
||||
values.toArray(new JavaValue[values.size()]), true);
|
||||
}
|
||||
};
|
||||
doOnJSThread(runnable);
|
||||
return settableFuture;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.github.pengfeizhou.doric.utils;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.github.pengfeizhou.doric.Doric;
|
||||
import com.github.pengfeizhou.jscore.JavaValue;
|
||||
@ -60,4 +62,5 @@ public class DoricUtils {
|
||||
return new JavaValue(String.valueOf(arg));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user