diff --git a/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java b/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java index 7fb4d328..733f65ea 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java @@ -17,6 +17,7 @@ package pub.doric; import android.os.Handler; import android.os.Looper; +import android.util.Log; import com.github.pengfeizhou.jscore.JSDecoder; @@ -76,7 +77,8 @@ public class DoricNativeDriver implements IDoricDriver { try { return doricJSEngine.invokeDoricMethod(method, args); } catch (Exception e) { - DoricLog.e("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage()); + doricJSEngine.onException(e); + doricJSEngine.onLogout(Log.ERROR, String.format("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage())); return new JSDecoder(null); } } @@ -105,7 +107,8 @@ public class DoricNativeDriver implements IDoricDriver { doricJSEngine.prepareContext(contextId, script, source); return true; } catch (Exception e) { - DoricLog.e("createContext %s error is %s", source, e.getLocalizedMessage()); + doricJSEngine.onException(e); + doricJSEngine.onLogout(Log.ERROR, String.format("createContext %s error is %s", source, e.getLocalizedMessage())); return false; } } @@ -121,7 +124,8 @@ public class DoricNativeDriver implements IDoricDriver { doricJSEngine.destroyContext(contextId); return true; } catch (Exception e) { - DoricLog.e("destroyContext %s error is %s", contextId, e.getLocalizedMessage()); + doricJSEngine.onException(e); + doricJSEngine.onLogout(Log.ERROR, String.format("destroyContext %s error is %s", contextId, e.getLocalizedMessage())); return false; } } diff --git a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java index 4e97e848..1ac8e7d8 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java @@ -66,6 +66,8 @@ public class DoricRegistry { private Map> pluginInfoMap = new HashMap<>(); private Map> nodeInfoMap = new HashMap<>(); + private Set monitors = new HashSet<>(); + private static void initRegistry(DoricRegistry doricRegistry) { for (DoricLibrary library : doricLibraries) { library.load(doricRegistry); @@ -146,4 +148,20 @@ public class DoricRegistry { public Map getEnvironmentVariables() { return extendedEnvValues; } + + public void registerMonitor(IDoricMonitor monitor) { + this.monitors.add(monitor); + } + + public void onException(Exception e) { + for (IDoricMonitor monitor : this.monitors) { + monitor.onException(e); + } + } + + public void onLogout(int type, String message) { + for (IDoricMonitor monitor : this.monitors) { + monitor.onLogout(type, message); + } + } } diff --git a/doric-android/doric/src/main/java/pub/doric/IDoricMonitor.java b/doric-android/doric/src/main/java/pub/doric/IDoricMonitor.java new file mode 100644 index 00000000..c7d99348 --- /dev/null +++ b/doric-android/doric/src/main/java/pub/doric/IDoricMonitor.java @@ -0,0 +1,40 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric; + +/** + * @Description: Monitor status of doric engine + * @Author: pengfei.zhou + * @CreateDate: 2020-01-10 + */ +public interface IDoricMonitor { + /** + * Called when native or js exception occurred in doric + * + * @param e exception which is thrown within doric sdk + * @see com.github.pengfeizhou.jscore.JSRuntimeException + */ + void onException(Exception e); + + /** + * @param type The priority/type of this log message. + * @param message The message you would like logged. + * @see android.util.Log#ERROR + * @see android.util.Log#WARN + * @see android.util.Log#DEBUG + */ + void onLogout(int type, String message); +} diff --git a/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java b/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java index b8a19d7a..bb64c914 100644 --- a/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java +++ b/doric-android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java @@ -23,6 +23,7 @@ import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.text.TextUtils; +import android.util.Log; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSONBuilder; @@ -34,6 +35,7 @@ import java.util.Map; import pub.doric.Doric; import pub.doric.DoricRegistry; +import pub.doric.IDoricMonitor; import pub.doric.extension.bridge.DoricBridgeExtension; import pub.doric.extension.timer.DoricTimerExtension; import pub.doric.utils.DoricConstant; @@ -45,7 +47,7 @@ import pub.doric.utils.DoricUtils; * @Author: pengfei.zhou * @CreateDate: 2019-07-18 */ -public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.TimerCallback { +public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.TimerCallback, IDoricMonitor { private HandlerThread handlerThread; private final Handler mJSHandler; @@ -68,6 +70,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time } }); mTimerExtension = new DoricTimerExtension(looper, this); + mDoricRegistry.registerMonitor(this); } public Handler getJSHandler() { @@ -116,17 +119,17 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time String message = args[1].string(); switch (type) { case "w": - DoricLog.suffix_w("_js", message); + mDoricRegistry.onLogout(Log.WARN, message); break; case "e": - DoricLog.suffix_e("_js", message); + mDoricRegistry.onLogout(Log.ERROR, message); break; default: - DoricLog.suffix_d("_js", message); + mDoricRegistry.onLogout(Log.INFO, message); break; } } catch (Exception e) { - e.printStackTrace(); + mDoricRegistry.onException(e); } return null; } @@ -144,13 +147,13 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time String name = args[0].string(); String content = mDoricRegistry.acquireJSBundle(name); if (TextUtils.isEmpty(content)) { - DoricLog.e("require js bundle:%s is empty", name); + mDoricRegistry.onLogout(Log.ERROR, String.format("require js bundle:%s is empty", name)); return new JavaValue(false); } mDoricJSE.loadJS(packageModuleScript(name, content), "Module://" + name); return new JavaValue(true); } catch (Exception e) { - e.printStackTrace(); + mDoricRegistry.onException(e); return new JavaValue(false); } } @@ -164,7 +167,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time args[1].number().longValue(), args[2].bool()); } catch (Exception e) { - e.printStackTrace(); + mDoricRegistry.onException(e); } return null; } @@ -175,7 +178,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time try { mTimerExtension.clearTimer(args[0].number().longValue()); } catch (Exception e) { - e.printStackTrace(); + mDoricRegistry.onException(e); } return null; } @@ -191,7 +194,7 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time JSDecoder jsDecoder = args[4]; return mDoricBridgeExtension.callNative(contextId, module, method, callbackId, jsDecoder); } catch (Exception e) { - e.printStackTrace(); + mDoricRegistry.onException(e); } return null; } @@ -199,10 +202,14 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time } private void initDoricRuntime() { - loadBuiltinJS(DoricConstant.DORIC_BUNDLE_SANDBOX); - String libName = DoricConstant.DORIC_MODULE_LIB; - String libJS = DoricUtils.readAssetFile(DoricConstant.DORIC_BUNDLE_LIB); - mDoricJSE.loadJS(packageModuleScript(libName, libJS), "Module://" + libName); + try { + loadBuiltinJS(DoricConstant.DORIC_BUNDLE_SANDBOX); + String libName = DoricConstant.DORIC_MODULE_LIB; + String libJS = DoricUtils.readAssetFile(DoricConstant.DORIC_BUNDLE_LIB); + mDoricJSE.loadJS(packageModuleScript(libName, libJS), "Module://" + libName); + } catch (Exception e) { + mDoricRegistry.onException(e); + } } @Override @@ -252,12 +259,34 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time try { invokeDoricMethod(DoricConstant.DORIC_TIMER_CALLBACK, timerId); } catch (Exception e) { - e.printStackTrace(); - DoricLog.e("Timer Callback error:%s", e.getLocalizedMessage()); + mDoricRegistry.onException(e); + mDoricRegistry.onLogout( + Log.ERROR, + String.format("Timer Callback error:%s", e.getLocalizedMessage())); } } public DoricRegistry getRegistry() { return mDoricRegistry; } + + @Override + public void onException(Exception e) { + e.printStackTrace(); + } + + @Override + public void onLogout(int type, String message) { + switch (type) { + case Log.ERROR: + DoricLog.suffix_e("_js", message); + break; + case Log.WARN: + DoricLog.suffix_w("_js", message); + break; + default: + DoricLog.suffix_d("_js", message); + break; + } + } } diff --git a/doric-android/doric/src/main/java/pub/doric/extension/bridge/DoricBridgeExtension.java b/doric-android/doric/src/main/java/pub/doric/extension/bridge/DoricBridgeExtension.java index e968a96d..c9c6bbf8 100644 --- a/doric-android/doric/src/main/java/pub/doric/extension/bridge/DoricBridgeExtension.java +++ b/doric-android/doric/src/main/java/pub/doric/extension/bridge/DoricBridgeExtension.java @@ -15,6 +15,8 @@ */ package pub.doric.extension.bridge; +import android.util.Log; + import pub.doric.DoricContext; import pub.doric.async.AsyncResult; @@ -44,22 +46,30 @@ public class DoricBridgeExtension { final DoricContext context = DoricContextManager.getContext(contextId); DoricMetaInfo pluginInfo = context.getDriver().getRegistry().acquirePluginInfo(module); if (pluginInfo == null) { - DoricLog.e("Cannot find plugin class:%s", module); + context.getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Cannot find plugin class:%s", module)); return new JavaValue(false); } final DoricJavaPlugin doricJavaPlugin = context.obtainPlugin(pluginInfo); if (doricJavaPlugin == null) { - DoricLog.e("Cannot obtain plugin instance:%s,method:%", module); + context.getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Cannot obtain plugin instance:%s,method:%s", module, methodName)); return new JavaValue(false); } final Method method = pluginInfo.getMethod(methodName); if (method == null) { - DoricLog.e("Cannot find plugin method in class:%s,method:%s", module, methodName); + context.getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Cannot find plugin method in class:%s,method:%s", module, methodName)); return new JavaValue(false); } DoricMethod doricMethod = method.getAnnotation(DoricMethod.class); if (doricMethod == null) { - DoricLog.e("Cannot find DoricMethod annotation in class:%s,method:%s", module, methodName); + context.getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Cannot find DoricMethod annotation in class:%s,method:%s", module, methodName)); return new JavaValue(false); } Callable callable = new Callable() { @@ -93,7 +103,10 @@ public class DoricBridgeExtension { try { return DoricUtils.toJavaObject(clz, jsDecoder); } catch (Exception e) { - DoricLog.e("createParam error:%s", e.getLocalizedMessage()); + context.getDriver().getRegistry().onException(e); + context.getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("createParam error:%s", e.getLocalizedMessage())); } return null; } diff --git a/doric-android/doric/src/main/java/pub/doric/plugin/ShaderPlugin.java b/doric-android/doric/src/main/java/pub/doric/plugin/ShaderPlugin.java index 67163a86..65015db6 100644 --- a/doric-android/doric/src/main/java/pub/doric/plugin/ShaderPlugin.java +++ b/doric-android/doric/src/main/java/pub/doric/plugin/ShaderPlugin.java @@ -16,6 +16,7 @@ package pub.doric.plugin; import android.text.TextUtils; +import android.util.Log; import pub.doric.DoricContext; import pub.doric.async.AsyncResult; @@ -78,8 +79,12 @@ public class ShaderPlugin extends DoricJavaPlugin { @Override public void onError(Throwable t) { - t.printStackTrace(); - DoricLog.e("Shader.render:error%s", t.getLocalizedMessage()); + if (t instanceof Exception) { + getDoricContext().getDriver().getRegistry().onException((Exception) t); + } + getDoricContext().getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Shader.render:error%s", t.getLocalizedMessage())); } @Override @@ -88,8 +93,11 @@ public class ShaderPlugin extends DoricJavaPlugin { } }); } catch (Exception e) { - e.printStackTrace(); - DoricLog.e("Shader.render:error%s", e.getLocalizedMessage()); + getDoricContext().getDriver().getRegistry().onException(e); + getDoricContext().getDriver().getRegistry().onLogout( + Log.ERROR, + String.format("Shader.render:error%s", e.getLocalizedMessage()) + ); } } @@ -166,7 +174,7 @@ public class ShaderPlugin extends DoricJavaPlugin { } } } catch (ArchiveException e) { - e.printStackTrace(); + getDoricContext().getDriver().getRegistry().onException(e); } return new JavaValue(true); }