Repository: incubator-weex Updated Branches: refs/heads/master edb442697 -> aad360553
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/common/WXPerformance.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/common/WXPerformance.java b/android/sdk/src/main/java/com/taobao/weex/common/WXPerformance.java index 8238041..8af7d85 100644 --- a/android/sdk/src/main/java/com/taobao/weex/common/WXPerformance.java +++ b/android/sdk/src/main/java/com/taobao/weex/common/WXPerformance.java @@ -18,25 +18,188 @@ */ package com.taobao.weex.common; +import android.os.Debug; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import android.text.TextUtils; + import com.taobao.weex.WXEnvironment; +import com.taobao.weex.performance.FpsCollector; +import com.taobao.weex.performance.MemUtils; +import com.taobao.weex.utils.WXViewUtils; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; public class WXPerformance { + @RestrictTo(Scope.LIBRARY) + public enum Dimension { + JSLibVersion, + WXSDKVersion, + pageName, + spm, + scheme, + cacheType, + requestType, + networkType, + connectionType, + zcacheInfo, + wxdim1, + wxdim2, + wxdim3, + wxdim4, + wxdim5, + bizType, + templateUrl, + useScroller + } + + public enum Measure { + /** + * range : [min,max) + */ + JSLibSize(0D, Double.MAX_VALUE), + //normal 300ms.. first install apk 30s ? + JSLibInitTime(0D, 50000D), + SDKInitTime(0D, 5000D), + SDKInitInvokeTime(0D, 5000D), + SDKInitExecuteTime(0D, 5000D), + JSTemplateSize(0D, 5000D), + pureNetworkTime(0D, 15000D), + networkTime(0D, 15000D), + fsCreateInstanceTime(0D, 3000D), + fsCallJsTotalTime(0D, 5000D), + fsCallJsTotalNum(0D, Double.MAX_VALUE), + fsCallNativeTotalTime(0D, 5000D), + fsCallNativeTotalNum(0D, Double.MAX_VALUE), + fsCallEventTotalNum(0D, Double.MAX_VALUE), + fsRenderTime(0D, 5000D), + fsRequestNum(0D, 100D), + callCreateFinishTime(0D, 10000D), + cellExceedNum(0D, Double.MAX_VALUE), + communicateTotalTime(0D, 5000D), + maxDeepViewLayer(0D, Double.MAX_VALUE), + maxDeepVDomLayer(0D, Double.MAX_VALUE), + componentCount(0D, Double.MAX_VALUE), + avgFps(0D, 61D), + timerCount(0D, Double.MAX_VALUE), + + MaxImproveMemory(0D, Double.MAX_VALUE), + BackImproveMemory(0D, Double.MAX_VALUE), + PushImproveMemory(0D, Double.MAX_VALUE), + measureTime1(0D, Double.MAX_VALUE), + measureTime2(0D, Double.MAX_VALUE), + measureTime3(0D, Double.MAX_VALUE), + measureTime4(0D, Double.MAX_VALUE), + measureTime5(0D, Double.MAX_VALUE), + + communicateTime(0D, 5000D), + screenRenderTime(0D, 5000D), + totalTime(0D, 5000D), + localReadTime(0D, 5000D), + templateLoadTime(0D, 5000D), + packageSpendTime(0D, 5000D), + syncTaskTime(0D, 5000D), + actualNetworkTime(0D, 5000D), + firstScreenJSFExecuteTime(0D, 5000D), + //.. + + fluency(0D, 101D), + imgSizeCount(0D, 2000D), + interactionTime(0D,10000D); + + + private double mMinRange, mMaxRange; + + Measure(double min, double max) { + this.mMinRange = min; + this.mMaxRange = max; + } + + public double getMinRange() { + return mMinRange; + } + + public double getMaxRange() { + return mMaxRange; + } + } + public static final String DEFAULT = "default"; + @RestrictTo(Scope.LIBRARY_GROUP) + public static final String CACHE_TYPE = "cacheType"; + + public static final int VIEW_LIMIT_HEIGHT = WXViewUtils.getScreenHeight() / 2; + public static final int VIEW_LIMIT_WIDTH = WXViewUtils.getScreenWidth() / 2; + public static boolean TRACE_DATA = WXEnvironment.isApkDebugable(); + /** - * Business unit, mandatory. If no business unit can be provided, set the field as default + * No longer needed. */ + @Deprecated public String bizType = "weex"; /** - * URL used for rendering view, optional + * Use {@link #pageName} instead. */ + @Deprecated public String templateUrl; + @RestrictTo(Scope.LIBRARY_GROUP) + public String cacheType = "unknown"; + + @RestrictTo(Scope.LIBRARY) + public long renderTimeOrigin; + + public long fsRenderTime; + + public long callCreateFinishTime; + + public long interactionTime; + + /** + * Time used for + * {@link com.taobao.weex.bridge.WXBridgeManager#createInstance(String, String, Map, String)} + */ + @RestrictTo(Scope.LIBRARY) + public long callCreateInstanceTime; + + + public long fsCallJsTotalTime; + + public int fsCallJsTotalNum; + + public long fsCallNativeTotalTime; + + public int fsCallNativeTotalNum; + + public int fsRequestNum; + + public int cellExceedNum; + + public int timerInvokeCount; + + public int fsCallEventTotalNum; + + public long avgFPS; + public long frameSum; + public long frameStartTime; + public long frameEndTime; + public double fluency = 100D; + + public long maxImproveMemory; + + public long backImproveMemory; + + public long pushImproveMemory; + + public long memTotalBeforeRender; + + /** * Time spent for reading, time unit is ms. */ @@ -65,9 +228,9 @@ public class WXPerformance { public long templateLoadTime; /** - * Time used for - * {@link com.taobao.weex.bridge.WXBridgeManager#createInstance(String, String, Map, String)} + * Use {@link #callCreateInstanceTime} instead. */ + @Deprecated public long communicateTime; /** @@ -96,18 +259,18 @@ public class WXPerformance { public long parseJsonTime; /** - * UpdateDomObj Time spent when rendering first screen + * UpdateDomObj Time spent when rendering first screen */ public long updateDomObjTime; /** - * ApplyUpdate Time spent when rendering first screen + * ApplyUpdate Time spent when rendering first screen */ public long applyUpdateTime; /** - * CssLayout Time spent when rendering first screen + * CssLayout Time spent when rendering first screen */ public long cssLayoutTime; @@ -133,11 +296,16 @@ public class WXPerformance { * view hierarchy */ public int maxDeepViewLayer; + + public int maxDeepVDomLayer; + + public double wrongImgSizeCount; + /** * 1:true * 0:false */ - public int useScroller=0; + public int useScroller = 0; /** * component Count @@ -171,101 +339,144 @@ public class WXPerformance { public String errMsg; private StringBuilder mErrMsgBuilder; - public String args=""; + public String args = ""; public String connectionType; public String requestType; + public String zCacheInfo; + /** *for network tracker */ - public String wxDims[] = new String [5]; - public long measureTimes[] = new long [5]; + /** + * TODO These dimensions will be moved to elsewhere + */ + @RestrictTo(Scope.LIBRARY) + @Deprecated + public String wxDims[] = new String[5]; - public WXPerformance(){ - mErrMsgBuilder=new StringBuilder(); + /** + * TODO These dimensions will be moved to elsewhere + */ + @RestrictTo(Scope.LIBRARY) + @Deprecated + public long measureTimes[] = new long[5]; + + public WXPerformance() { + mErrMsgBuilder = new StringBuilder(); } - public Map<String,Double> getMeasureMap(){ - Map<String,Double> quotas = new HashMap<>(); - quotas.put("JSTemplateSize", JSTemplateSize); - quotas.put("JSLibSize", JSLibSize); - quotas.put("communicateTime", (double)communicateTime); - quotas.put("screenRenderTime", (double)screenRenderTime); - quotas.put("totalTime", totalTime); - quotas.put("localReadTime", localReadTime); - quotas.put("JSLibInitTime", (double)JSLibInitTime); - quotas.put("networkTime", (double)networkTime); - quotas.put("templateLoadTime", (double)templateLoadTime); - quotas.put("SDKInitInvokeTime",(double)WXEnvironment.sSDKInitInvokeTime); - quotas.put("SDKInitExecuteTime",(double)WXEnvironment.sSDKInitExecuteTime); - quotas.put("firstScreenJSFExecuteTime",(double) firstScreenJSFExecuteTime); - quotas.put("componentCount",(double)componentCount); - quotas.put("actualNetworkTime",(double)actualNetworkTime); - quotas.put("pureNetworkTime",(double)pureNetworkTime); - quotas.put("syncTaskTime",(double)syncTaskTime); - quotas.put("packageSpendTime",(double)packageSpendTime); - quotas.put("SDKInitTime",(double)WXEnvironment.sSDKInitTime); - quotas.put("maxDeepViewLayer", (double) maxDeepViewLayer); - quotas.put("useScroller", (double) useScroller); - quotas.put("measureTime1", (double) measureTimes[0]); - quotas.put("measureTime2", (double) measureTimes[1]); - quotas.put("measureTime3", (double) measureTimes[2]); - quotas.put("measureTime4", (double) measureTimes[3]); - quotas.put("measureTime5", (double) measureTimes[4]); - return quotas; + public static void init() { + if (WXPerformance.TRACE_DATA) { + FpsCollector.getInstance().init(); + } } - public Map<String,String> getDimensionMap(){ - Map<String,String> quotas = new HashMap<>(); - quotas.put("bizType", bizType); - quotas.put("templateUrl", templateUrl); - quotas.put("pageName", pageName); - quotas.put("JSLibVersion", JSLibVersion); - quotas.put("WXSDKVersion", WXSDKVersion); - quotas.put("connectionType",connectionType); - quotas.put("requestType",requestType); - quotas.put("wxdim1", wxDims[0]); - quotas.put("wxdim2", wxDims[1]); - quotas.put("wxdim3", wxDims[2]); - quotas.put("wxdim4", wxDims[3]); - quotas.put("wxdim5", wxDims[4]); - return quotas; + public Map<String, Double> getMeasureMap() { + double fsRenderTime; + if (this.fsRenderTime != 0) { + fsRenderTime = this.fsRenderTime - renderTimeOrigin; + } else { + if (totalTime != 0) { + fsRenderTime = totalTime; + } else { + fsRenderTime = -1; + } + } + Map<String, Double> quotas = new HashMap<>(); + quotas.put(Measure.JSLibSize.toString(), JSLibSize); + quotas.put(Measure.JSLibInitTime.toString(), (double) JSLibInitTime); + quotas.put(Measure.SDKInitTime.toString(), (double) WXEnvironment.sSDKInitTime); + quotas.put(Measure.SDKInitInvokeTime.toString(), (double) WXEnvironment.sSDKInitInvokeTime); + quotas.put(Measure.SDKInitExecuteTime.toString(), (double) WXEnvironment.sSDKInitExecuteTime); + quotas.put(Measure.JSTemplateSize.toString(), JSTemplateSize); + quotas.put(Measure.pureNetworkTime.toString(), (double) pureNetworkTime); + quotas.put(Measure.networkTime.toString(), (double) networkTime); + quotas.put(Measure.fsCreateInstanceTime.toString(), (double) (callCreateInstanceTime - renderTimeOrigin)); + quotas.put(Measure.fsCallJsTotalTime.toString(), (double) fsCallJsTotalTime); + quotas.put(Measure.fsCallJsTotalNum.toString(), (double) fsCallJsTotalNum); + quotas.put(Measure.fsCallNativeTotalTime.toString(), (double) fsCallNativeTotalTime); + quotas.put(Measure.fsCallNativeTotalNum.toString(), (double) fsCallNativeTotalNum); + quotas.put(Measure.fsRenderTime.toString(), fsRenderTime); + quotas.put(Measure.fsRequestNum.toString(), (double) fsRequestNum); + quotas.put(Measure.communicateTotalTime.toString(), totalTime); + quotas.put(Measure.maxDeepViewLayer.toString(), (double) maxDeepViewLayer); + quotas.put(Measure.maxDeepVDomLayer.toString(), (double) maxDeepVDomLayer); + quotas.put(Measure.componentCount.toString(), (double) componentCount); + quotas.put(Measure.cellExceedNum.toString(), (double) cellExceedNum); + quotas.put(Measure.timerCount.toString(), (double) timerInvokeCount); + quotas.put(Measure.avgFps.toString(), (double) avgFPS); + quotas.put(Measure.fluency.toString(), fluency); + quotas.put(Measure.MaxImproveMemory.toString(), 0D); + quotas.put(Measure.BackImproveMemory.toString(), (double) backImproveMemory); + quotas.put(Measure.PushImproveMemory.toString(), 0D); + + quotas.put(Measure.fsCallEventTotalNum.toString(), (double) fsCallEventTotalNum); + quotas.put(Measure.callCreateFinishTime.toString(), (double) callCreateFinishTime); + quotas.put(Measure.imgSizeCount.toString(), wrongImgSizeCount); + quotas.put(Measure.interactionTime.toString(), (double) interactionTime); + + // TODO the following attribute is no longer needed and will be deleted soon. + quotas.put(Measure.screenRenderTime.toString(), (double) screenRenderTime); + quotas.put(Measure.communicateTime.toString(), (double) communicateTime); + quotas.put(Measure.localReadTime.toString(), localReadTime); + quotas.put(Measure.templateLoadTime.toString(), (double) templateLoadTime); + quotas.put(Measure.firstScreenJSFExecuteTime.toString(), (double) firstScreenJSFExecuteTime); + quotas.put(Measure.actualNetworkTime.toString(), (double) actualNetworkTime); + quotas.put(Measure.syncTaskTime.toString(), (double) syncTaskTime); + quotas.put(Measure.packageSpendTime.toString(), (double) packageSpendTime); + + // TODO These attribute will be moved to elsewhere + quotas.put(Measure.measureTime1.toString(), (double) measureTimes[0]); + quotas.put(Measure.measureTime2.toString(), (double) measureTimes[1]); + quotas.put(Measure.measureTime3.toString(), (double) measureTimes[2]); + quotas.put(Measure.measureTime4.toString(), (double) measureTimes[3]); + quotas.put(Measure.measureTime5.toString(), (double) measureTimes[4]); + return quotas; } - public static String[] getDimensions(){ - return new String[]{"bizType","templateUrl","pageName","JSLibVersion","WXSDKVersion","connectionType","requestType" - ,"wxdim1","wxdim2","wxdim3","wxdim4","wxdim5"}; + public Map<String, String> getDimensionMap() { + Map<String, String> quotas = new HashMap<>(); + quotas.put(Dimension.JSLibVersion.toString(), JSLibVersion); + quotas.put(Dimension.WXSDKVersion.toString(), WXSDKVersion); + quotas.put(Dimension.pageName.toString(), pageName); + quotas.put(Dimension.requestType.toString(), requestType); + quotas.put(Dimension.networkType.toString(), "unknown"); + quotas.put(Dimension.connectionType.toString(), connectionType); + quotas.put(Dimension.zcacheInfo.toString(), zCacheInfo); + quotas.put(Dimension.cacheType.toString(), cacheType); + quotas.put(Dimension.useScroller.toString(), String.valueOf(useScroller)); + + // TODO These attribute will be moved to elsewhere + // Extra Dimension for 3rd developers. + quotas.put(Dimension.wxdim1.toString(), wxDims[0]); + quotas.put(Dimension.wxdim2.toString(), wxDims[1]); + quotas.put(Dimension.wxdim3.toString(), wxDims[2]); + quotas.put(Dimension.wxdim4.toString(), wxDims[3]); + quotas.put(Dimension.wxdim5.toString(), wxDims[4]); + + // TODO the following attribute is no longer needed and will be deleted soon. + quotas.put(Dimension.bizType.toString(), bizType); + quotas.put(Dimension.templateUrl.toString(), templateUrl); + return quotas; } - public static String[] getMeasures(){ - return new String[]{"JSTemplateSize", - "JSLibSize", - "communicateTime", - "screenRenderTime", - "totalTime", - "localReadTime", - "JSLibInitTime", - "networkTime", - "componentCount", - "templateLoadTime", - "SDKInitInvokeTime", - "SDKInitExecuteTime", - "SDKInitTime", - "packageSpendTime", - "syncTaskTime", - "pureNetworkTime", - "actualNetworkTime", - "firstScreenJSFExecuteTime", - "maxDeepViewLayer", - "useScroller", - "measureTime1", - "measureTime2", - "measureTime3", - "measureTime4", - "measureTime5" - }; + public static String[] getDimensions() { + List<String> ret = new LinkedList<>(); + for (Dimension dimension : Dimension.values()) { + ret.add(dimension.toString()); + } + return ret.toArray(new String[ret.size()]); + } + + public static String[] getMeasures() { + List<String> ret = new LinkedList<>(); + for (Measure measure : Measure.values()) { + ret.add(measure.toString()); + } + return ret.toArray(new String[ret.size()]); } @Override @@ -285,8 +496,8 @@ public class WXPerformance { + ",packageSpendTime:" + packageSpendTime + ",connectionType:" + connectionType + ",requestType:" + requestType - + ",initInvokeTime:"+WXEnvironment.sSDKInitInvokeTime+",initExecuteTime:"+WXEnvironment.sSDKInitExecuteTime - + ",SDKInitTime:"+ WXEnvironment.sSDKInitTime + + ",initInvokeTime:" + WXEnvironment.sSDKInitInvokeTime + ",initExecuteTime:" + WXEnvironment.sSDKInitExecuteTime + + ",SDKInitTime:" + WXEnvironment.sSDKInitTime + ",totalTime:" + totalTime + ",JSLibVersion:" + JSLibVersion + ",WXSDKVersion:" + WXSDKVersion + ",errCode:" + errCode + ",renderFailedDetail:" + renderFailedDetail + ",arg:" + args @@ -294,21 +505,22 @@ public class WXPerformance { } return super.toString(); } - public String getPerfData(){ - return "networkTime:" + networkTime - + " actualNetworkTime:" + actualNetworkTime - + " connectionType:" + connectionType - + " requestType:" + requestType - + " firstScreenRenderTime:" + screenRenderTime - + " firstScreenJSFExecuteTime:" + firstScreenJSFExecuteTime - + " componentCount:" + componentCount - + " JSTemplateSize:" + JSTemplateSize - + " SDKInitTime:" + WXEnvironment.sSDKInitTime - + " totalTime:" + totalTime - + " JSLibVersion:" + JSLibVersion - + " WXSDKVersion:" + WXSDKVersion - + " pageName:" + pageName - + " useScroller:" + useScroller; + + public String getPerfData() { + return "networkTime:" + networkTime + + " actualNetworkTime:" + actualNetworkTime + + " connectionType:" + connectionType + + " requestType:" + requestType + + " firstScreenRenderTime:" + screenRenderTime + + " firstScreenJSFExecuteTime:" + firstScreenJSFExecuteTime + + " componentCount:" + componentCount + + " JSTemplateSize:" + JSTemplateSize + + " SDKInitTime:" + WXEnvironment.sSDKInitTime + + " totalTime:" + totalTime + + " JSLibVersion:" + JSLibVersion + + " WXSDKVersion:" + WXSDKVersion + + " pageName:" + pageName + + " useScroller:" + useScroller; } @@ -319,4 +531,65 @@ public class WXPerformance { public void appendErrMsg(CharSequence msg) { mErrMsgBuilder.append(msg); } -} + + + private FpsRecorder mFpsRecorder = new FpsRecorder(); + + public void beforeInstanceRender(String instanceId) { + renderTimeOrigin = System.currentTimeMillis(); + if (WXPerformance.TRACE_DATA) { + if (TextUtils.isEmpty(instanceId)) { + return; + } + Debug.MemoryInfo mem = MemUtils.getMemoryInfo(WXEnvironment.getApplication()); + if (null != mem) { + memTotalBeforeRender = mem.getTotalPss(); + } + FpsCollector.getInstance().registerListener(instanceId, mFpsRecorder); + } + } + + // public void onInstanceEndRender(String instanceId,boolean isFirstScreen){ + // + // } + + + public void afterInstanceDestroy(String instanceId) { + if (WXPerformance.TRACE_DATA) { + if (TextUtils.isEmpty(instanceId)) { + return; + } + FpsCollector.getInstance().unRegister(instanceId); + Debug.MemoryInfo mem = MemUtils.getMemoryInfo(WXEnvironment.getApplication()); + if (null != mem) { + backImproveMemory = mem.getTotalPss() - memTotalBeforeRender; + } + if (mFpsRecorder.totalFpsCount > 0) { + avgFPS = mFpsRecorder.totalFpsCount / mFpsRecorder.totalFpsCount; + fluency = (double) mFpsRecorder.fluncyFpsPointCount / (double) mFpsRecorder.totalFpsCount; + } + } + } + + private class FpsRecorder implements FpsCollector.IFPSCallBack { + + private final long FLUENCY_FPS_LIMIT = 35; + + private long totalFpsFrame; + private long totalFpsCount; + private long fluncyFpsPointCount; + private final long LIMIT_LONG = Long.MAX_VALUE - 1000; + + @Override + public void fps(int fps) { + if (totalFpsFrame >= LIMIT_LONG || totalFpsCount >= Long.MAX_VALUE) { + return; + } + totalFpsFrame += fps; + totalFpsCount++; + if (fps >= FLUENCY_FPS_LIMIT) { + fluncyFpsPointCount++; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java index 5bc24ae..af00be9 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomManager.java @@ -170,7 +170,7 @@ public final class WXDomManager { WXLogUtils.e("WXDomManager", className + " Is Invalid Action"); if(className.contains("CreateFinishAction")){ WXExceptionUtils.commitCriticalExceptionRT(instanceId, - WXErrorCode.WX_KEY_EXCEPTION_DOM_ACTION_FIRST_ACTION.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_ACTION_FIRST_ACTION, "executeAction", WXErrorCode.WX_KEY_EXCEPTION_DOM_ACTION_FIRST_ACTION.getErrorMsg() + "|current action is" +className, null); instance.setmIsCommitedDomAtionExp(true); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java index 5e8b5bb..7897d44 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java @@ -115,10 +115,10 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject private boolean cloneThis = false; - public void traverseTree(Consumer...consumers){ + public int traverseTree(Consumer...consumers){ long startNanos = System.nanoTime(); if (consumers == null) { - return; + return 0; } for (Consumer consumer:consumers){ @@ -127,11 +127,14 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject int count = childCount(); WXDomObject child; + int maxChildDep = 0; for (int i = 0; i < count; ++i) { child = getChild(i); - child.traverseTree(consumers); + int depNum = child.traverseTree(consumers); + maxChildDep= maxChildDep > depNum? maxChildDep:depNum; } mDomThreadNanos += (System.nanoTime() - startNanos); + return maxChildDep+1; } /** http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java index b6a27fb..08ca2e3 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java @@ -71,7 +71,7 @@ public abstract class AbstractAddElementAction extends TraceableAction implement parentC.addChild(createdComponent); }else{ WXLogUtils.e("[generateComponentTree] " + getStatementName() + " create dom component failed name " + child.getType()); - WXExceptionUtils.commitCriticalExceptionRT(context.getInstanceId(), getErrorCode().getErrorCode(), "generateComponentTree", " create dom component failed name " + child.getType(), null); + WXExceptionUtils.commitCriticalExceptionRT(context.getInstanceId(), getErrorCode(), "generateComponentTree", " create dom component failed name " + child.getType(), null); } } } @@ -94,12 +94,11 @@ public abstract class AbstractAddElementAction extends TraceableAction implement if (instance == null) { return; } - String errCode = getErrorCode().getErrorCode(); String errMsg = getErrorMsg(); if (dom == null) { // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, errCode); - WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), errCode, "addDomInternal", errMsg, null); + WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), getErrorCode(), "addDomInternal", errMsg, null); } //only non-root has parent. @@ -110,16 +109,21 @@ public abstract class AbstractAddElementAction extends TraceableAction implement if (domObject == null || context.getDomByRef(domObject.getRef()) != null) { WXLogUtils.e("[DOMActionContextImpl] " + getStatementName() + " error,DOM object is null or already registered!!"); // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, errCode); - WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), errCode, "addDomInternal", errMsg, null); + WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), getErrorCode(), "addDomInternal", errMsg, null); return; } appendDomToTree(context, domObject); Stopwatch.split("appendDomToTree"); - domObject.traverseTree( + int maxDomDep = domObject.traverseTree( context.getAddDOMConsumer(), context.getApplyStyleConsumer() ); + + if (instance.getMaxDomDeep()< maxDomDep){ + instance.setMaxDomDeep(maxDomDep); + } + Stopwatch.split("traverseTree"); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java index 87f5d56..00bccce 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java @@ -150,5 +150,6 @@ final class AddElementAction extends AbstractAddElementAction { WXLogUtils.e("add component failed.", e); mErrMsg.append("add component failed.").append(WXLogUtils.getStackTrace(e)); } + instance.onElementChange(); } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java index 2e3b469..58ccf6a 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddEventAction.java @@ -69,7 +69,7 @@ class AddEventAction extends TraceableAction implements DOMAction, RenderAction if(!"_documentElement".equals(mRef)){//Rax framework WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_ADD_EVENT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_ADD_EVENT, "addEvent", WXErrorCode.WX_KEY_EXCEPTION_DOM_ADD_EVENT.getErrorMsg() + "| domObject is null |" +sbErr.toString(),null); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/AnimationAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AnimationAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AnimationAction.java index fa2246f..a0d689f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AnimationAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AnimationAction.java @@ -128,7 +128,7 @@ class AnimationAction implements DOMAction, RenderAction { } } catch (RuntimeException e) { WXExceptionUtils.commitCriticalExceptionRT(context.getInstance().getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION, "animationAction", WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION.getErrorMsg() + WXLogUtils.getStackTrace(e),null); WXLogUtils.e(TAG, WXLogUtils.getStackTrace(e)); @@ -174,7 +174,7 @@ class AnimationAction implements DOMAction, RenderAction { } } catch (RuntimeException e) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION, "animationAction", WXErrorCode.WX_KEY_EXCEPTION_DOM_ANIMATION.getErrorMsg() + WXLogUtils.getStackTrace(e),null); WXLogUtils.e(TAG, WXLogUtils.getStackTrace(e)); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/ModuleInvocationAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/ModuleInvocationAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/ModuleInvocationAction.java index 12c70ab..327f9a3 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/ModuleInvocationAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/ModuleInvocationAction.java @@ -64,7 +64,7 @@ class ModuleInvocationAction implements DOMAction, RenderAction { helper.invoke(mWXModule,mInvoker,mArgs); } catch (Exception e) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_MODULEINVO.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_MODULEINVO, "updateAttr", WXErrorCode.WX_KEY_EXCEPTION_DOM_MODULEINVO.getErrorMsg() + "callModuleMethod >>> invoke module:" + mWXModule.getClass().getSimpleName() + " failed. " + WXLogUtils.getStackTrace(e),null); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/MoveElementAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/MoveElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/MoveElementAction.java index e447283..a103858 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/MoveElementAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/MoveElementAction.java @@ -59,7 +59,7 @@ final class MoveElementAction implements DOMAction, RenderAction { || parentObject == null || parentObject.hasNewLayout()) { if (instance != null) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_MOVE_ELEMENT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_MOVE_ELEMENT, "moveElement", WXErrorCode.WX_KEY_EXCEPTION_DOM_MOVE_ELEMENT.getErrorMsg() + "domObject = " + domObject http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveElementAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveElementAction.java index 36babe5..144d3ec 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveElementAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveElementAction.java @@ -51,7 +51,7 @@ final class RemoveElementAction implements DOMAction, RenderAction { if (instance != null) { // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_REMOVEELEMENT); WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT, "removeElement", WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT.getErrorMsg() + "domObject is null",null); } @@ -62,7 +62,7 @@ final class RemoveElementAction implements DOMAction, RenderAction { if (instance != null) { // instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_REMOVEELEMENT); WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT, "removeElement", WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_ELEMENT.getErrorMsg() + "parent is null",null); } @@ -85,6 +85,10 @@ final class RemoveElementAction implements DOMAction, RenderAction { clearRegistryForComponent(context, component); parent.remove(component, true); context.unregisterComponent(mRef); + WXSDKInstance instance = context.getInstance(); + if (null != instance){ + instance.onElementChange(); + } } private void clearRegistryForComponent(RenderActionContext context, WXComponent component) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveEventAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveEventAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveEventAction.java index 511ada6..79f55af 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveEventAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/RemoveEventAction.java @@ -57,7 +57,7 @@ class RemoveEventAction implements DOMAction, RenderAction { if (domObject == null) { if (instance != null) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_EVENT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_EVENT, "updateAttr", WXErrorCode.WX_KEY_EXCEPTION_DOM_REMOVE_EVENT.getErrorMsg() + "domObject is null",null); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java index ac6ca5d..92d8513 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java @@ -58,7 +58,7 @@ class UpdateAttributeAction extends TraceableAction implements DOMAction, Render if (domObject == null) { if (instance != null) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_ATTRS.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_ATTRS, "updateAttr", WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_ATTRS.getErrorMsg() + "domObject is null",null); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java index 0c9a08a..a289bca 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateStyleAction.java @@ -68,7 +68,7 @@ class UpdateStyleAction extends TraceableAction implements DOMAction, RenderActi if (domObject == null) { if (instance != null) { WXExceptionUtils.commitCriticalExceptionRT(instance.getInstanceId(), - WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_STYLE.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_STYLE, "updateStyle", WXErrorCode.WX_KEY_EXCEPTION_DOM_UPDATE_STYLE.getErrorMsg() + "domObject is null",null); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/performance/FpsCollector.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/FpsCollector.java b/android/sdk/src/main/java/com/taobao/weex/performance/FpsCollector.java new file mode 100644 index 0000000..5819bd2 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/performance/FpsCollector.java @@ -0,0 +1,113 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 com.taobao.weex.performance; + + +import android.os.Build; +import android.os.Handler; +import android.support.annotation.RequiresApi; +import android.view.Choreographer; + +import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.common.WXPerformance; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author chenpeihan + * @date 2017/12/12 + */ + +public class FpsCollector { + + private Map<String, IFPSCallBack> mListenerMap = new ConcurrentHashMap<>(); + private AtomicBoolean mHasInit = new AtomicBoolean(false); + + + private static class SingleTonHolder { + + private static FpsCollector INSTANCE = new FpsCollector(); + } + + public static FpsCollector getInstance() { + return SingleTonHolder.INSTANCE; + } + + public void init() { + if (!WXEnvironment.isApkDebugable()) { + return; + } + if (mHasInit.compareAndSet(false, true)) { + WXSDKManager.getInstance().postOnUiThread(new Runnable() { + @Override + public void run() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && WXPerformance.TRACE_DATA) { + Choreographer.getInstance().postFrameCallback(new OnFrameListener()); + } + } + }, 0); + + } + } + + + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) + private class OnFrameListener implements Choreographer.FrameCallback { + + private int mFrameCount = 0; + private long mTimeBegin = 0; + + @Override + public void doFrame(long frameTimeNanos) { + Choreographer.getInstance().postFrameCallback(this); + if (mTimeBegin == 0) { + mTimeBegin = System.currentTimeMillis(); + mFrameCount++; + return; + } + long timeDiff = System.currentTimeMillis() - mTimeBegin; + if (timeDiff < 1000) { + mFrameCount++; + return; + } + for (Map.Entry<String, IFPSCallBack> entry : mListenerMap.entrySet()) { + entry.getValue().fps(mFrameCount); + } + WXAnalyzerDataTransfer.transferFps(mFrameCount); + + mTimeBegin = 0; + mFrameCount = 0; + } + } + + public interface IFPSCallBack { + + void fps(int fps); + } + + + public void registerListener(String key, IFPSCallBack listener) { + mListenerMap.put(key, listener); + } + + public void unRegister(String key) { + mListenerMap.remove(key); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/performance/IWXAnalyzer.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/IWXAnalyzer.java b/android/sdk/src/main/java/com/taobao/weex/performance/IWXAnalyzer.java new file mode 100644 index 0000000..cbd170c --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/performance/IWXAnalyzer.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 com.taobao.weex.performance; + + +/** + * @author zhongcang + * @date 2018/2/28 + */ + +public interface IWXAnalyzer { + + /** + * + * @param group dataGroup + * @param module dataModule in group + * @param type dataType + * @param data data (json) + */ + void transfer(String group, String module, String type, String data); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/performance/MemUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/MemUtils.java b/android/sdk/src/main/java/com/taobao/weex/performance/MemUtils.java new file mode 100644 index 0000000..9933988 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/performance/MemUtils.java @@ -0,0 +1,80 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 com.taobao.weex.performance; + +import android.app.ActivityManager; +import android.content.Context; +import android.os.Build; +import android.os.Debug; +import android.util.Log; + +import com.taobao.weex.WXEnvironment; + +/** + * @author chenpeihan + * @date 2017/12/12 + */ + +public class MemUtils { + + /** + * bad performance ,40ms-60ms + */ + public static Debug.MemoryInfo getMemoryInfo(Context context) { + long start = System.currentTimeMillis(); + if (null == context){ + return null; + } + Debug.MemoryInfo meminfo = null; + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + if (activityManager != null) { + if (Build.VERSION.SDK_INT >= 23) { + int[] pids = {android.os.Process.myPid()}; + Debug.MemoryInfo[] meminfos = activityManager.getProcessMemoryInfo(pids); + if (meminfos != null && meminfos.length > 0) { + meminfo = meminfos[0]; + } + } else { + meminfo = new Debug.MemoryInfo(); + Debug.getMemoryInfo(meminfo); + int privateDirty = meminfo.getTotalPrivateDirty(); + if (privateDirty == 0) { + Debug.getMemoryInfo(meminfo); + } + } + } + if (WXEnvironment.isApkDebugable()){ + Log.d("MemUtils", "getMemoryInfo , time :"+(System.currentTimeMillis() -start)); + } + + return meminfo; + } + + public static long getTotalPss(Context context) { + + long totalPss = 0L; + + Debug.MemoryInfo meminfo = getMemoryInfo(context); + if (meminfo != null) { + totalPss = meminfo.getTotalPss(); + } + return totalPss; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java b/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java new file mode 100644 index 0000000..129dcec --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java @@ -0,0 +1,138 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 com.taobao.weex.performance; + +import com.taobao.weex.WXEnvironment; +import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.WXSDKManager; +import com.taobao.weex.common.WXErrorCode; +import com.taobao.weex.common.WXJSExceptionInfo; +import com.taobao.weex.common.WXPerformance; + +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; + +/** + * @author zhongcang + * @date 2018/2/28 + */ + +public class WXAnalyzerDataTransfer { + + private static final String GROUP = "WXAnalyzer"; + private static final String MODULE_PERFORMANCE = "WXPerformance"; + private static final String MODULE_ERROR = "WXError"; + + + public static void transferPerformance(WXPerformance performance, String instanceId) { + if (!WXEnvironment.isApkDebugable()) { + return; + } + List<IWXAnalyzer> transferList = WXSDKManager.getInstance().getWXAnalyzerList(); + if (null == transferList || transferList.size() == 0) { + return; + } + + + WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId); + if (null == instance) { + return; + } + String data = ""; + try { + JSONObject dimensionMap = new JSONObject(); + JSONObject measureMap = new JSONObject(); + + for (Map.Entry<String, String> entry : performance.getDimensionMap().entrySet()) { + dimensionMap.put(entry.getKey(), entry.getValue()); + } + for (Map.Entry<String, Double> entry : performance.getMeasureMap().entrySet()) { + measureMap.put(entry.getKey(), entry.getValue()); + } + + data = new JSONObject() + .put("instanceId", instanceId) + .put("url", instance.getBundleUrl()) + .put("dimensionMap", dimensionMap) + .put("measureMap", measureMap) + .toString(); + + } catch (Exception e) { + e.printStackTrace(); + } + for (IWXAnalyzer transfer : transferList) { + transfer.transfer(GROUP, MODULE_PERFORMANCE, "instance", data); + } + } + + public static void transferError(WXJSExceptionInfo exceptionInfo, String instanceId) { + if (!WXEnvironment.isApkDebugable()) { + return; + } + List<IWXAnalyzer> transferList = WXSDKManager.getInstance().getWXAnalyzerList(); + if (null == transferList || transferList.size() == 0) { + return; + } + + WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(instanceId); + if (null == instance) { + return; + } + WXErrorCode errorCode = exceptionInfo.getErrCode(); + String data = ""; + try { + data = new JSONObject() + .put("instanceId", instanceId) + .put("url", instance.getBundleUrl()) + .put("errorCode", errorCode.getErrorCode()) + .put("errorMsg", errorCode.getErrorMsg()) + .put("errorGroup", errorCode.getErrorGroup()) + .toString(); + } catch (Exception e) { + e.printStackTrace(); + } + for (IWXAnalyzer transfer : transferList) { + transfer.transfer(GROUP, MODULE_ERROR, errorCode.getErrorType().toString(), data); + } + } + + public static void transferFps(long fps) { + if (!WXEnvironment.isApkDebugable()) { + return; + } + List<IWXAnalyzer> transferList = WXSDKManager.getInstance().getWXAnalyzerList(); + if (null == transferList || transferList.size() == 0) { + return; + } + String data = ""; + try { + data = new JSONObject().put("fps", fps).toString(); + } catch (Exception e) { + e.printStackTrace(); + } + for (IWXAnalyzer transfer : transferList) { + transfer.transfer(GROUP, MODULE_PERFORMANCE, "fps", data); + } + } + +// @Override +// public void transfer2(String tag, String module, String type, String data) { +// WXLogUtils.d(tag, module + ":" + type + ":" + data); +// } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java index 6522c9b..39a0358 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java @@ -66,6 +66,7 @@ import com.taobao.weex.bridge.EventResult; import com.taobao.weex.bridge.Invoker; import com.taobao.weex.common.Constants; import com.taobao.weex.common.IWXObject; +import com.taobao.weex.common.WXPerformance; import com.taobao.weex.common.WXRuntimeException; import com.taobao.weex.dom.ImmutableDomObject; import com.taobao.weex.dom.WXDomHandler; @@ -535,6 +536,10 @@ public abstract class WXComponent<T extends View> implements IWXObject, IWXActi return; } + if (realHeight >= WXPerformance.VIEW_LIMIT_HEIGHT && realWidth>=WXPerformance.VIEW_LIMIT_WIDTH){ + mInstance.getWXPerformance().cellExceedNum++; + } + mAbsoluteY = (int) (nullParent?0:mParent.getAbsoluteY() + mDomObj.getLayoutY()); mAbsoluteX = (int) (nullParent?0:mParent.getAbsoluteX() + mDomObj.getLayoutX()); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java index 6002a5d..87f5859 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java @@ -30,10 +30,10 @@ import android.widget.ImageView; import com.taobao.weappplus_sdk.R; import com.taobao.weex.IWXRenderListener; import com.taobao.weex.WXEnvironment; -import com.taobao.weex.WXRenderErrorCode; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; import com.taobao.weex.common.Constants; +import com.taobao.weex.common.WXErrorCode; import com.taobao.weex.common.WXPerformance; import com.taobao.weex.common.WXRenderStrategy; import com.taobao.weex.dom.WXDomObject; @@ -112,8 +112,8 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis public static class ClickToReloadListener implements OnNestedInstanceEventListener { @Override public void onException(NestedContainer container, String errCode, String msg) { - if (TextUtils.equals(errCode, WXRenderErrorCode.DegradPassivityCode. - WX_DEGRAD_ERR_NETWORK_BUNDLE_DOWNLOAD_FAILED.getDegradErrorCode()) && container instanceof WXEmbed) { + if (TextUtils.equals(errCode, WXErrorCode. + WX_DEGRAD_ERR_NETWORK_BUNDLE_DOWNLOAD_FAILED.getErrorCode()) && container instanceof WXEmbed) { final WXEmbed comp = ((WXEmbed)container); final ImageView imageView = new ImageView(comp.getContext()); imageView.setImageResource(R.drawable.error); @@ -327,8 +327,8 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis if(TextUtils.isEmpty(url)){ mListener.mEventListener.onException(this, - WXRenderErrorCode.DegradPassivityCode.WX_DEGRAD_ERR_BUNDLE_CONTENTTYPE_ERROR.getDegradErrorCode(), - WXRenderErrorCode.DegradPassivityCode.WX_DEGRAD_ERR_BUNDLE_CONTENTTYPE_ERROR.getDegradErrorMsg() + "!!wx embed src url is null" + WXErrorCode.WX_DEGRAD_ERR_BUNDLE_CONTENTTYPE_ERROR.getErrorCode(), + WXErrorCode.WX_DEGRAD_ERR_BUNDLE_CONTENTTYPE_ERROR.getErrorMsg() + "!!wx embed src url is null" ); return sdkInstance; } @@ -347,7 +347,7 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis super.setVisibility(visibility); boolean visible = TextUtils.equals(visibility, Constants.Value.VISIBLE); if(mIsVisible != visible){ - + if (!TextUtils.isEmpty(src) && visible) { if (mNestedInstance == null) { loadContent(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java index f307d8a..dcaefdf 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXImage.java @@ -22,6 +22,7 @@ import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; +import android.graphics.Bitmap; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.net.Uri; @@ -31,6 +32,8 @@ import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.TextUtils; +import android.util.Log; +import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ImageView.ScaleType; @@ -323,6 +326,7 @@ public class WXImage extends WXComponent<ImageView> { fireEvent(Constants.Event.ONLOAD, params); } } + monitorImgSize(imageView); } }); @@ -437,6 +441,25 @@ public class WXImage extends WXComponent<ImageView> { }); } + private void monitorImgSize(ImageView imageView){ + if (null == imageView){ + return; + } + WXSDKInstance instance = getInstance(); + if (null == instance){ + return; + } + ViewGroup.LayoutParams params =imageView.getLayoutParams(); + Drawable img = imageView.getDrawable(); + if (null == params || null ==img){ + return; + } + + if (img.getIntrinsicHeight() * img.getIntrinsicWidth() > imageView.getMeasuredHeight() * + imageView.getMeasuredWidth()){ + instance.getWXPerformance().wrongImgSizeCount++; + } + } public void destroy() { if(getHostView() instanceof WXImageView){ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java index 2c048c1..8745b54 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java @@ -41,6 +41,7 @@ import com.taobao.weex.bridge.WXHashMap; import com.taobao.weex.bridge.WXJSObject; import com.taobao.weex.common.Destroyable; import com.taobao.weex.common.WXModule; +import com.taobao.weex.common.WXPerformance; import com.taobao.weex.dom.action.Actions; import com.taobao.weex.utils.WXJsonUtils; import com.taobao.weex.utils.WXLogUtils; @@ -69,6 +70,14 @@ public class WXTimerModule extends WXModule implements Destroyable, Handler.Call public void setTimeout(@IntRange(from = 1) int funcId, @FloatRange(from = 0) float delay) { if(mWXSDKInstance != null) { postOrHoldMessage(MODULE_TIMEOUT, funcId, (int) delay, Integer.parseInt(mWXSDKInstance.getInstanceId())); + WXSDKManager.getInstance().postOnUiThread(new Runnable() { + @Override + public void run() { + if (null != mWXSDKInstance){ + mWXSDKInstance.getWXPerformance().timerInvokeCount++; + } + } + },0); } } @@ -76,6 +85,14 @@ public class WXTimerModule extends WXModule implements Destroyable, Handler.Call public void setInterval(@IntRange(from = 1) int funcId, @FloatRange(from = 0) float interval) { if(mWXSDKInstance != null) { postOrHoldMessage(MODULE_INTERVAL, funcId, (int) interval, Integer.parseInt(mWXSDKInstance.getInstanceId())); + WXSDKManager.getInstance().postOnUiThread(new Runnable() { + @Override + public void run() { + if (null != mWXSDKInstance){ + mWXSDKInstance.getWXPerformance().timerInvokeCount++; + } + } + },0); } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/utils/WXExceptionUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXExceptionUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXExceptionUtils.java index 4fbcafc..c571ba2 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXExceptionUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXExceptionUtils.java @@ -18,14 +18,22 @@ */ package com.taobao.weex.utils; +import android.app.Activity; +import android.content.Context; import android.support.annotation.Nullable; import android.text.TextUtils; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.WXSDKManager; import com.taobao.weex.adapter.IWXJSExceptionAdapter; +import com.taobao.weex.performance.IWXAnalyzer; +import com.taobao.weex.common.WXErrorCode; import com.taobao.weex.common.WXJSExceptionInfo; import com.taobao.weex.common.WXPerformance; +import com.taobao.weex.performance.WXAnalyzerDataTransfer; + +import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -39,6 +47,7 @@ public class WXExceptionUtils { */ public static String degradeUrl = "BundleUrlDefaultDegradeUrl"; + /** * commitCriticalExceptionRT eg:JsRuntime Exception or JsFramework Init Exception * @param instanceId @@ -48,7 +57,7 @@ public class WXExceptionUtils { * @param extParams */ public static void commitCriticalExceptionRT(@Nullable final String instanceId, - @Nullable final String errCode, + @Nullable final WXErrorCode errCode, @Nullable final String function, @Nullable final String exception, @Nullable final Map<String,String> extParams ) { @@ -59,11 +68,22 @@ public class WXExceptionUtils { String instanceIdCommit = "InstanceIdDefalut"; String exceptionMsgCommit = exception; Map<String, String> commitMap = extParams; + if (null == commitMap){ + commitMap = new HashMap<>(); + } + commitMap.put("activity","empty"); if (!TextUtils.isEmpty(instanceId)) { instanceIdCommit = instanceId; instance = WXSDKManager.getInstance().getSDKInstance(instanceId); + if (null != instance && instance.getContainerView() != null){ + Context c = instance.getContainerView().getContext(); + if (c instanceof Activity){ + commitMap.put("activity",c.getClass().getSimpleName()); + } + } + if (null != instance && instance.getContext() != null && instance.getBundleUrl() != null) { bundleUrlCommit = instance.getBundleUrl(); exceptionMsgCommit += "\n instance.getTemplateInfo()==" + instance.getTemplateInfo(); @@ -72,8 +92,8 @@ public class WXExceptionUtils { bundleUrlCommit = degradeUrl; } else bundleUrlCommit = WXSDKInstance.requestUrl; - } - } + } + } } else {//instance is null for instance id is null if (!TextUtils.isEmpty(WXSDKInstance.requestUrl)) { bundleUrlCommit = WXSDKInstance.requestUrl; @@ -84,10 +104,12 @@ public class WXExceptionUtils { } } + exceptionCommit = new WXJSExceptionInfo(instanceIdCommit, bundleUrlCommit, errCode, function, exceptionMsgCommit, commitMap); if (adapter != null) { - exceptionCommit = new WXJSExceptionInfo(instanceIdCommit, bundleUrlCommit, errCode, function, exceptionMsgCommit, commitMap); adapter.onJSException(exceptionCommit); - WXLogUtils.e(exceptionCommit.toString()); } + + WXAnalyzerDataTransfer.transferError(exceptionCommit, instanceId); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java index e8ec6bc..b03fb95 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java @@ -28,7 +28,9 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; public class WXLogUtils { @@ -39,11 +41,12 @@ public class WXLogUtils { private static StringBuilder builder = new StringBuilder(50); private static HashMap<String, Class> clazzMaps = new HashMap<>(2); - private static JsLogWatcher jsLogWatcher; + private static List<JsLogWatcher> jsLogWatcherList; private static LogWatcher sLogWatcher; static { clazzMaps.put(CLAZZ_NAME_LOG_UTIL, loadClass(CLAZZ_NAME_LOG_UTIL)); + jsLogWatcherList = new ArrayList<>(); } private static Class loadClass(String clazzName) { @@ -124,18 +127,20 @@ public class WXLogUtils { log(tag, msg, LogLevel.DEBUG); if(WXEnvironment.isApkDebugable()){//sLogLevel in debug mode is "LogLevel.DEBUG" - if ("jsLog".equals(tag) && jsLogWatcher != null) { - if (msg.endsWith("__DEBUG")) { - jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__DEBUG", "")); - } else if (msg.endsWith("__INFO")) { - jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__INFO", "")); - } else if (msg.endsWith("__WARN")) { - jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__WARN", "")); - } else if (msg.endsWith("__ERROR")) { - jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__ERROR", "")); - } else { - jsLogWatcher.onJsLog(Log.DEBUG, msg); - } + if ("jsLog".equals(tag) && jsLogWatcherList != null && jsLogWatcherList.size() > 0) { + for (JsLogWatcher jsLogWatcher : jsLogWatcherList) { + if (msg.endsWith("__DEBUG")) { + jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__DEBUG", "")); + } else if (msg.endsWith("__INFO")) { + jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__INFO", "")); + } else if (msg.endsWith("__WARN")) { + jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__WARN", "")); + } else if (msg.endsWith("__ERROR")) { + jsLogWatcher.onJsLog(Log.DEBUG, msg.replace("__ERROR", "")); + } else { + jsLogWatcher.onJsLog(Log.DEBUG, msg); + } + } } /** This log method will be invoked from jni code, so try to extract loglevel from message. **/ @@ -289,7 +294,9 @@ public class WXLogUtils { } public static void setJsLogWatcher(JsLogWatcher watcher) { - jsLogWatcher = watcher; + if (!jsLogWatcherList.contains(watcher)) { + jsLogWatcherList.add(watcher); + } } public static void setLogWatcher(LogWatcher watcher) { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java index 60d45d8..7fc1009 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXSoInstallMgrSdk.java @@ -112,7 +112,7 @@ public class WXSoInstallMgrSdk { String cpuType = _cpuType(); if (cpuType.equalsIgnoreCase(MIPS) ) { WXExceptionUtils.commitCriticalExceptionRT(null, - WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT, "initSo", "[WX_KEY_EXCEPTION_SDK_INIT_CPU_NOT_SUPPORT] for android cpuType is MIPS", null); return false; @@ -140,7 +140,7 @@ public class WXSoInstallMgrSdk { } catch (Exception | Error e2) { if (cpuType.contains(ARMEABI) || cpuType.contains(X86)) { WXExceptionUtils.commitCriticalExceptionRT(null, - WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT, "initSo", "[WX_KEY_EXCEPTION_SDK_INIT_CPU_NOT_SUPPORT] for android cpuType is " +cpuType + "\n Detail Error is: " +e2.getMessage(), null); @@ -295,7 +295,7 @@ public class WXSoInstallMgrSdk { } }catch(Throwable e ){ WXExceptionUtils.commitCriticalExceptionRT(null, - WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT.getErrorCode(), + WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT, "checkSoIsValid", "[WX_KEY_EXCEPTION_SDK_INIT_CPU_NOT_SUPPORT] for " + "weex so size check fail exception :"+e.getMessage(), null); @@ -375,7 +375,7 @@ public class WXSoInstallMgrSdk { } catch (Throwable e) { initSuc = false; WXExceptionUtils.commitCriticalExceptionRT(null, - "-9001", + WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT_CPU_NOT_SUPPORT, "_loadUnzipSo", "[WX_KEY_EXCEPTION_SDK_INIT_WX_ERR_COPY_FROM_APK] " + "\n Detail Msg is : " + e.getMessage(), null); @@ -473,7 +473,7 @@ public class WXSoInstallMgrSdk { } catch (java.io.IOException e) { e.printStackTrace(); WXExceptionUtils.commitCriticalExceptionRT(null, - "-9001", + WXErrorCode.WX_KEY_EXCEPTION_SDK_INIT_CPU_NOT_SUPPORT, "unZipSelectedFiles", "[WX_KEY_EXCEPTION_SDK_INIT_unZipSelectedFiles] " + "\n Detail msg is: " + e.getMessage(), null); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/495c7aca/android/sdk/src/test/java/com/taobao/weex/utils/WXExceptionUtilsTest.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/test/java/com/taobao/weex/utils/WXExceptionUtilsTest.java b/android/sdk/src/test/java/com/taobao/weex/utils/WXExceptionUtilsTest.java index 81c9804..8709304 100644 --- a/android/sdk/src/test/java/com/taobao/weex/utils/WXExceptionUtilsTest.java +++ b/android/sdk/src/test/java/com/taobao/weex/utils/WXExceptionUtilsTest.java @@ -20,6 +20,7 @@ package com.taobao.weex.utils; import com.taobao.weappplus_sdk.BuildConfig; import com.taobao.weex.WXEnvironment; +import com.taobao.weex.common.WXErrorCode; import org.junit.Before; import org.junit.Rule; @@ -67,7 +68,7 @@ public class WXExceptionUtilsTest { Map testMap = new HashMap<String, String>(); testMap.put("weexUrl","weexurltest"); testMap.put("bundleUrl","bundleUrltest"); - Exp.commitCriticalExceptionRT("1","test","test","test",testMap); - Exp.commitCriticalExceptionRT("1","test","test","test",null); + Exp.commitCriticalExceptionRT("1", WXErrorCode.WX_ERR_TEST,"test","test",testMap); + Exp.commitCriticalExceptionRT("1",WXErrorCode.WX_ERR_TEST,"test","test",null); } } \ No newline at end of file
