blob: 0be0965774a38a909c6c0813e9615801918c361c [file] [log] [blame]
/**
* 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 org.apache.weex.performance;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import org.apache.weex.WXEnvironment;
import org.apache.weex.WXSDKInstance;
import org.apache.weex.WXSDKManager;
import org.apache.weex.bridge.WXBridgeManager;
import org.apache.weex.common.WXErrorCode;
import org.apache.weex.common.WXPerformance;
import org.apache.weex.common.WXRenderStrategy;
import org.apache.weex.ui.component.WXComponent;
import org.apache.weex.utils.WXExceptionUtils;
import org.apache.weex.utils.WXLogUtils;
import org.apache.weex.utils.WXUtils;
public class WXInstanceApm {
public static final String WEEX_PAGE_TOPIC = "weex_page";
/************** properties *****************/
public static final String KEY_PROPERTIES_ERROR_CODE = "wxErrorCode";
//public static final String KEY_PAGE_PROPERTIES_LAUNCH_ID = "wxLaunchId";
public static final String KEY_PAGE_PROPERTIES_BIZ_ID = "wxBizID";
public static final String KEY_PAGE_PROPERTIES_BUBDLE_URL = "wxBundleUrl";
public static final String KEY_PAGE_PROPERTIES_JSLIB_VERSION = "wxJSLibVersion";
public static final String KEY_PAGE_PROPERTIES_WEEX_VERSION = "wxSDKVersion";
public static final String KEY_PAGE_PROPERTIES_REQUEST_TYPE = "wxRequestType";
public static final String KEY_PAGE_PROPERTIES_CACHE_TYPE = "wxCacheType";
public static final String KEY_PAGE_PROPERTIES_CACHE_INFO = "wxZCacheInfo";
public static final String KEY_PAGE_PROPERTIES_JS_FM_INI = "wxJsFrameworkInit";
public static final String KEY_PAGE_PROPERTIES_CONTAINER_NAME = "wxContainerName";
public static final String KEY_PAGE_PROPERTIES_INSTANCE_TYPE = "wxInstanceType";
public static final String KEY_PAGE_PROPERTIES_PARENT_PAGE = "wxParentPage";
public static final String KEY_PAGE_PROPERTIES_BUNDLE_TYPE = "wxBundleType";
public static final String KEY_PAGE_PROPERTIES_RENDER_TYPE = "wxRenderType";
public static final String KEY_PAGE_PROPERTIES_UIKIT_TYPE = "wxUIKitType";
/************** stages *****************/
public static final String KEY_PAGE_STAGES_CONTAINER_READY = "wxContainerReady";
public static final String KEY_PAGE_STAGES_DOWN_BUNDLE_START = "wxStartDownLoadBundle";
public static final String KEY_PAGE_STAGES_DOWN_BUNDLE_END = "wxEndDownLoadBundle";
public static final String KEY_PAGE_STAGES_RENDER_ORGIGIN = "wxRenderTimeOrigin";
public static final String KEY_PAGE_STAGES_LOAD_BUNDLE_START = "wxStartLoadBundle";
public static final String KEY_PAGE_STAGES_LOAD_BUNDLE_END = "wxEndLoadBundle";
public static final String KEY_PAGE_STAGES_FIRST_INTERACTION_VIEW = "wxFirstInteractionView";
public static final String KEY_PAGE_STAGES_CREATE_FINISH= "wxJSBundleCreateFinish";
public static final String KEY_PAGE_STAGES_FSRENDER = "wxFsRender";
public static final String KEY_PAGE_STAGES_NEW_FSRENDER = "wxNewFsRender";
public static final String KEY_PAGE_STAGES_END_EXCUTE_BUNDLE = "wxEndExecuteBundle";
public static final String KEY_PAGE_STAGES_INTERACTION = "wxInteraction";
public static final String KEY_PAGE_STAGES_DESTROY = "wxDestroy";
//Custom preprocessing start, called when activity created or other time. Called by other activity
public static final String KEY_PAGE_STAGES_CUSTOM_PREPROCESS_START = "wxCustomPreprocessStart";
//Custom preprocessing end, called when you'are able to start weex render. Called by other activity
public static final String KEY_PAGE_STAGES_CUSTOM_PREPROCESS_END = "wxCustomPreprocessEnd";
/************** stats *****************/
public static final String KEY_PAGE_STATS_BUNDLE_SIZE = "wxBundleSize";
public static final String KEY_PAGE_STATS_FS_CALL_JS_TIME = "wxFSCallJsTotalTime";
public static final String KEY_PAGE_STATS_FS_CALL_JS_NUM = "wxFSCallJsTotalNum";
public static final String KEY_PAGE_STATS_FS_TIMER_NUM = "wxFSTimerCount";
public static final String KEY_PAGE_STATS_FS_CALL_NATIVE_TIME = "wxFSCallNativeTotalTime";
public static final String KEY_PAGE_STATS_FS_CALL_NATIVE_NUM = "wxFSCallNativeTotalNum";
public static final String KEY_PAGE_STATS_FS_CALL_EVENT_NUM = "wxFSCallEventTotalNum";
public static final String KEY_PAGE_STATS_FS_REQUEST_NUM = "wxFSRequestNum";
public static final String KEY_PAGE_STATS_CELL_EXCEED_NUM = "wxCellExceedNum";
public static final String KEY_PAGE_STATS_MAX_DEEP_VIEW = "wxMaxDeepViewLayer";
public static final String KEY_PAGE_STATS_MAX_DEEP_DOM = "wxMaxDeepVDomLayer";
public static final String KEY_PAGE_STATS_MAX_COMPONENT_NUM = "wxMaxComponentCount";
public static final String KEY_PAGE_STATS_WRONG_IMG_SIZE_COUNT = "wxWrongImgSizeCount";
public static final String KEY_PAGE_STATS_EMBED_COUNT = "wxEmbedCount";
public static final String KEY_PAGE_STATS_LARGE_IMG_COUNT = "wxLargeImgMaxCount";
public static final String KEY_PAGE_STATS_BODY_RATIO = "wxBodyRatio";
public static final String KEY_PAGE_STATS_SCROLLER_NUM = "wxScrollerCount";
public static final String KEY_PAGE_STATS_CELL_DATA_UN_RECYCLE_NUM = "wxCellDataUnRecycleCount";
public static final String KEY_PAGE_STATS_CELL_UN_RE_USE_NUM = "wxCellUnReUseCount";
public static final String KEY_PAGE_STATS_IMG_UN_RECYCLE_NUM = "wxImgUnRecycleCount";
public static final String KEY_PAGE_STATS_I_SCREEN_VIEW_COUNT = "wxInteractionScreenViewCount";
public static final String KEY_PAGE_STATS_I_ALL_VIEW_COUNT = "wxInteractionAllViewCount";
public static final String KEY_PAGE_STATS_I_COMPONENT_CREATE_COUNT = "wxInteractionComponentCreateCount";
public static final String KEY_PAGE_ANIM_BACK_NUM = "wxAnimationInBackCount";
public static final String KEY_PAGE_TIMER_BACK_NUM = "wxTimerInBackCount";
public static final String KEY_PAGE_STATS_ACTUAL_DOWNLOAD_TIME = "wxActualNetworkTime";
public static final String KEY_PAGE_STATS_IMG_LOAD_NUM = "wxImgLoadCount";
public static final String KEY_PAGE_STATS_IMG_LOAD_SUCCESS_NUM = "wxImgLoadSuccessCount";
public static final String KEY_PAGE_STATS_IMG_LOAD_FAIL_NUM = "wxImgLoadFailCount";
public static final String KEY_PAGE_STATS_NET_NUM = "wxNetworkRequestCount";
public static final String KEY_PAGE_STATS_NET_SUCCESS_NUM = "wxNetworkRequestSuccessCount";
public static final String KEY_PAGE_STATS_NET_FAIL_NUM = "wxNetworkRequestFailCount";
public static final String KEY_PAGE_STATS_JSLIB_INIT_TIME = "wxJSLibInitTime";
public static final String KEY_PAGE_STATS_VIEW_CREATE_COST = "wxViewCost";
public static final String KEY_PAGE_STATS_COMPONENT_CREATE_COST = "wxComponentCost";
public static final String KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST = "wxExecJsCallBack";
public static final String KEY_PAGE_STATS_LAYOUT_TIME = "wxLayoutTime";
/************** value *****************/
public static final String VALUE_ERROR_CODE_DEFAULT = "0";
public static final String VALUE_BUNDLE_LOAD_LENGTH = "wxLoadedLength";
private String mInstanceId;
private IWXApmMonitorAdapter apmInstance;
private Map<String, Double> recordStatsMap;
public final Map<String, Long> stageMap;
private Map<String,Object> mPropertiesMap;
private boolean isFSEnd;
private boolean mHasInit = false;
private boolean mEnd = false;
private boolean hasRecordFistInteractionView =false;
public final Map<String,Object> extInfo;
public boolean forceStopRecordInteraction = false;
public Rect instanceRect;
public String reportPageName;
public boolean hasReportLayerOverDraw = false;
public boolean hasAddView;
private Handler mUIHandler;
public Set<String> exceptionRecord = new CopyOnWriteArraySet<String>();
private double interactionLayoutTime;
public long componentCreateTime;
private long interactionComponentCreateTime;
public long viewCreateTime;
private long interactionViewCreateTime;
//next version
private long wxExecJsCallBackTime;
private long interactionJsCallBackTime;
private boolean mHasRecordDetailData = false;
/**
* send performance value to js
**/
private boolean hasSendInteractionToJS = false;
public volatile boolean isReady = true;
public WXInstanceApm(String instanceId) {
mInstanceId = instanceId;
extInfo = new ConcurrentHashMap<>();
stageMap = new ConcurrentHashMap<>();
mUIHandler = new Handler(Looper.getMainLooper());
recordStatsMap = new ConcurrentHashMap<>();
mPropertiesMap = new ConcurrentHashMap<>();
IApmGenerator generator = WXSDKManager.getInstance().getApmGenerater();
if (null != generator) {
apmInstance = generator.generateApmInstance(WEEX_PAGE_TOPIC);
}
}
public void onInstanceReady(boolean isPreDownLoad){
this.isReady = true;
if (isPreDownLoad){
onStage(KEY_PAGE_STAGES_DOWN_BUNDLE_START);
}
doInit();
for (Map.Entry<String,Long> stage:stageMap.entrySet()){
sendStageInfo(stage.getKey(),stage.getValue());
}
for (Map.Entry<String,Double> stats:recordStatsMap.entrySet()){
sendStats(stats.getKey(),stats.getValue());
}
for (Map.Entry<String,Object> p:mPropertiesMap.entrySet()){
sendProperty(p.getKey(),p.getValue());
}
}
/**
* record event
*/
public void onEvent(String name, Object value) {
if (null == apmInstance) {
return;
}
apmInstance.onEvent(name, value);
}
/**
* record stage
*/
public void onStage(String name) {
long time = WXUtils.getFixUnixTime();
onStageWithTime(name,time);
}
/**
*
* @param name stage
* @param time unixTime ,plz use WXUtils.getFixUnixTime
*/
public void onStageWithTime(String name,long time){
if (mEnd){
return;
}
if (null == name){
return;
}
stageMap.put(name,time);
if (isReady){
sendStageInfo(name,time);
}
}
private void sendStageInfo(String name,long time){
if(WXAnalyzerDataTransfer.isOpenPerformance){
WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"stage",name,time);
}
if (KEY_PAGE_STAGES_RENDER_ORGIGIN.equalsIgnoreCase(name)){
mUIHandler.postDelayed(jsPerformanceCallBack,8000);
}
if (null == apmInstance) {
return;
}
apmInstance.onStage(name, time);
}
private Runnable jsPerformanceCallBack = new Runnable() {
@Override
public void run() {
sendPerformanceToJS();
}
};
/**
* record property
*/
public void addProperty(String key, Object value) {
if (mEnd){
return;
}
if (null == key || null == value){
return;
}
mPropertiesMap.put(key,value);
if (isReady){
sendProperty(key,value);
}
}
private void sendProperty(String key,Object value){
if(WXAnalyzerDataTransfer.isOpenPerformance){
WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"properties",key,value);
}
if (null == apmInstance) {
return;
}
apmInstance.addProperty(key, value);
}
/**
* record statistic
*/
public void addStats(String key, double value) {
if (mEnd){
return;
}
if (null == key){
return;
}
recordStatsMap.put(key,value);
if (isReady){
sendStats(key,value);
}
}
private void sendStats(String key,double value){
if(WXAnalyzerDataTransfer.isOpenPerformance){
WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"stats",key,value);
}
if (null == apmInstance) {
return;
}
apmInstance.addStats(key, value);
}
public boolean hasInit(){
return mHasInit;
}
/**
* start record
*/
public void doInit() {
if (!isReady){
return;
}
if (mHasInit){
return;
}
mHasInit = true;
if (null == apmInstance) {
return;
}
apmInstance.onStart(mInstanceId);
WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
String url = null == instance ? "unKnowUrl" : instance.getBundleUrl();
addProperty(KEY_PAGE_PROPERTIES_BUBDLE_URL, url);
addProperty(KEY_PROPERTIES_ERROR_CODE, VALUE_ERROR_CODE_DEFAULT);
addProperty(KEY_PAGE_PROPERTIES_JSLIB_VERSION, WXEnvironment.JS_LIB_SDK_VERSION);
addProperty(KEY_PAGE_PROPERTIES_WEEX_VERSION, WXEnvironment.WXSDK_VERSION);
addStats("wxReInitCount", WXBridgeManager.reInitCount);
if (null != instance){
addProperty(KEY_PAGE_PROPERTIES_UIKIT_TYPE, instance.getRenderType());
}
addProperty("wxUseRuntimeApi",WXEnvironment.sUseRunTimeApi);
if (instance != null && (instance.isUsingEaglePlugin()
|| instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER_BINARY //todo only for compat.
|| instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER
)) {
addProperty(KEY_PAGE_PROPERTIES_RENDER_TYPE, WXEnvironment.EAGLE);
}
if (null != instance) {
for (Map.Entry<String, String> entry : instance.getContainerInfo().entrySet()) {
addProperty(entry.getKey(), entry.getValue());
}
}
}
public void setPageName(String pageName) {
if (TextUtils.isEmpty(pageName)) {
WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
if (null != instance) {
pageName = instance.getContainerInfo().get(KEY_PAGE_PROPERTIES_CONTAINER_NAME);
}
}
reportPageName = null == apmInstance?pageName:apmInstance.parseReportUrl(pageName);
reportPageName = TextUtils.isEmpty(reportPageName) ? "emptyPageName" : reportPageName;
addProperty(KEY_PAGE_PROPERTIES_BIZ_ID, reportPageName);
}
public void onAppear(){
if (null == apmInstance) {
return;
}
apmInstance.onAppear();
}
public void onDisAppear(){
if (null == apmInstance) {
return;
}
apmInstance.onDisappear();
}
/**
* end record
*/
public void onEnd() {
if (null == apmInstance || mEnd) {
return;
}
new Handler(Looper.getMainLooper()).removeCallbacks(delayCollectDataTask);
recordPerformanceDetailData();
exceptionRecord.clear();
mUIHandler.removeCallbacks(jsPerformanceCallBack);
onStage(KEY_PAGE_STAGES_DESTROY);
if (mHasInit && null != apmInstance){
apmInstance.onEnd();
}
mEnd = true;
if (WXEnvironment.isApkDebugable()){
printLog();
}
}
public void doDelayCollectData(){
new Handler(Looper.getMainLooper()).postDelayed(delayCollectDataTask,8000);
}
private Runnable delayCollectDataTask = new Runnable() {
@Override
public void run() {
recordPerformanceDetailData();
}
};
private void printLog(){
Long startDownLoad = stageMap.get(KEY_PAGE_STAGES_DOWN_BUNDLE_START);
Long endDownLoad = stageMap.get(KEY_PAGE_STAGES_DOWN_BUNDLE_END);
Long interaction = stageMap.get(KEY_PAGE_STAGES_INTERACTION);
Long containerReady = stageMap.get(KEY_PAGE_STAGES_CONTAINER_READY);
if (null != endDownLoad && null != startDownLoad){
WXLogUtils.d("test->", "downLoadTime: "+ (endDownLoad - startDownLoad));
}
if (null != endDownLoad && null != interaction){
WXLogUtils.d("test->", "renderTime: "+ (interaction - endDownLoad));
}
if (null != containerReady && null !=interaction){
WXLogUtils.d("test->", "showTime: "+ (interaction - containerReady));
}
}
public void arriveNewFsRenderTime(){
if (null == apmInstance){
return;
}
onStage(WXInstanceApm.KEY_PAGE_STAGES_NEW_FSRENDER);
}
public void arriveFSRenderTime() {
if (null == apmInstance){
return;
}
isFSEnd = true;
onStage(WXInstanceApm.KEY_PAGE_STAGES_FSRENDER);
}
public void arriveInteraction(WXComponent targetComponent) {
if (null == apmInstance || null == targetComponent || targetComponent.getInstance() == null) {
return;
}
if (WXAnalyzerDataTransfer.isOpenPerformance){
WXAnalyzerDataTransfer.transferInteractionInfo(targetComponent);
}
if (null == apmInstance){
return;
}
WXPerformance performanceRecord = targetComponent.getInstance().getWXPerformance();
if (null == performanceRecord){
return;
}
long curTime = WXUtils.getFixUnixTime();
if (WXAnalyzerDataTransfer.isInteractionLogOpen()){
Log.d(WXAnalyzerDataTransfer.INTERACTION_TAG, "[client][wxinteraction]"
+ targetComponent.getInstance().getInstanceId()
+","+targetComponent.getComponentType()
+","+targetComponent.getRef()
+","+targetComponent.getStyles()
+","+targetComponent.getAttrs()
);
}
if (!hasRecordFistInteractionView){
onStage(KEY_PAGE_STAGES_FIRST_INTERACTION_VIEW);
hasRecordFistInteractionView = true;
}
if (forceStopRecordInteraction){
return;
}
long now = WXUtils.getFixUnixTime();
if (now - preUpdateTime > 50){
//for performance, reduce jni calls
WXBridgeManager.getInstance().onInteractionTimeUpdate(mInstanceId);
preUpdateTime = now;
}
interactionComponentCreateTime = componentCreateTime;
interactionViewCreateTime = viewCreateTime;
Double layoutTime = recordStatsMap.get("wxLayoutTime");
interactionLayoutTime = layoutTime ==null? 0:layoutTime;
performanceRecord.interactionTime = curTime - performanceRecord.renderUnixTimeOrigin;
performanceRecord.interactionRealUnixTime = System.currentTimeMillis();
onStageWithTime(KEY_PAGE_STAGES_INTERACTION,curTime);
updateDiffStats(KEY_PAGE_STATS_I_SCREEN_VIEW_COUNT, 1);
updateMaxStats(KEY_PAGE_STATS_I_ALL_VIEW_COUNT, performanceRecord.localInteractionViewAddCount);
WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
if (null != instance) {
updateMaxStats(KEY_PAGE_STATS_I_COMPONENT_CREATE_COUNT, instance.getWXPerformance().componentCount);
}
}
private long preUpdateTime = 0;
public void updateFSDiffStats(String name, double diffValue) {
if (null == apmInstance || isFSEnd) {
return;
}
updateDiffStats(name, diffValue);
}
public void recordPerformanceDetailData(){
if (mHasRecordDetailData){
return;
}
mHasRecordDetailData = true;
addStats(KEY_PAGE_STATS_VIEW_CREATE_COST,interactionViewCreateTime);
addStats(KEY_PAGE_STATS_COMPONENT_CREATE_COST,interactionComponentCreateTime);
addStats(KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST,interactionJsCallBackTime);
addStats(KEY_PAGE_STATS_LAYOUT_TIME,interactionLayoutTime);
}
public void updateDiffStats(String name, double diffValue) {
if (null == apmInstance) {
return;
}
Double preVal = recordStatsMap.containsKey(name) ? recordStatsMap.get(name) : 0;
//fix by use ConcurrentHashMap,but not sure,so report if error still happen
if (null == preVal){
WXExceptionUtils.commitCriticalExceptionRT(
"",
WXErrorCode.WX_ERR_HASH_MAP_TMP,
"updateDiffStats",
"key : "+name,
null
);
return;
}
double currentValue = preVal + diffValue;
addStats(name, currentValue);
}
public void updateMaxStats(String name, double currentVal) {
if (null == apmInstance) {
return;
}
Double maxValue = recordStatsMap.containsKey(name) ? recordStatsMap.get(name) : 0;
//fix by use ConcurrentHashMap,but not sure,so report if error still happen
if (null == maxValue){
WXExceptionUtils.commitCriticalExceptionRT(
"",
WXErrorCode.WX_ERR_HASH_MAP_TMP,
"updateMaxStats",
"key : "+name,
null
);
return;
}
if (maxValue < currentVal) {
maxValue = currentVal;
addStats(name, maxValue);
}
}
public void updateRecordInfo(Map<String, Object> extParams) {
if (null == apmInstance || null == extParams) {
return;
}
addPropeyFromExtParms(KEY_PAGE_PROPERTIES_REQUEST_TYPE, KEY_PAGE_PROPERTIES_REQUEST_TYPE, extParams);
addPropeyFromExtParms("cacheType", KEY_PAGE_PROPERTIES_CACHE_TYPE, extParams);
addPropeyFromExtParms("zCacheInfo", KEY_PAGE_PROPERTIES_CACHE_INFO, extParams);
addStats(KEY_PAGE_STATS_JSLIB_INIT_TIME, WXEnvironment.sJSLibInitTime);
addProperty(KEY_PAGE_PROPERTIES_JS_FM_INI, WXEnvironment.JsFrameworkInit);
Object wxNetLibDownBundleTime = extParams.get("actualNetworkTime");
if (wxNetLibDownBundleTime instanceof Long) {
updateDiffStats(KEY_PAGE_STATS_ACTUAL_DOWNLOAD_TIME, ((Long)wxNetLibDownBundleTime).doubleValue());
}
}
private void addPropeyFromExtParms(String fromKey, String toKey, Map<String, Object> extParams) {
Object value = extParams.get(fromKey);
if (value instanceof String) {
addProperty(toKey, value);
}
}
/************** called by IWXHttpAdapter implementer *****************/
public void actionNetRequest() {
if (!isFSEnd) {
updateFSDiffStats(WXInstanceApm.KEY_PAGE_STATS_FS_REQUEST_NUM, 1);
}
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_NUM, 1);
}
public void actionNetResult(boolean succeed, String errorCode) {
if (succeed) {
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_SUCCESS_NUM, 1);
} else {
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_FAIL_NUM, 1);
}
}
/************** called by IWXImgLoaderAdapter implementer *****************/
public void actionLoadImg() {
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_NUM, 1);
}
public void actionLoadImgResult(boolean succeed, String errorCode) {
if (succeed) {
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_SUCCESS_NUM, 1);
} else {
updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_FAIL_NUM, 1);
}
}
public void sendPerformanceToJS() {
if (hasSendInteractionToJS) {
return;
}
hasSendInteractionToJS = true;
WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
if (null == instance) {
return;
}
Map<String,String> sendProperties = new HashMap<>(2);
sendProperties.put(KEY_PAGE_PROPERTIES_BIZ_ID,reportPageName);
sendProperties.put(KEY_PAGE_PROPERTIES_BUBDLE_URL,instance.getBundleUrl());
Map<String,Long> sendStage = new HashMap<>(1);
sendStage.put(KEY_PAGE_STAGES_INTERACTION,instance.getWXPerformance().interactionRealUnixTime);
Map<String, Object> data = new HashMap<>(2);
data.put("stage",sendStage);
data.put("properties",sendProperties);
instance.fireGlobalEventCallback("wx_apm", data);
}
public String toPerfString() {
Long start = stageMap.get(KEY_PAGE_STAGES_RENDER_ORGIGIN);
Long end = stageMap.get(KEY_PAGE_STAGES_INTERACTION);
Long wxNewFsRender = stageMap.get(KEY_PAGE_STAGES_NEW_FSRENDER);
StringBuilder builder = new StringBuilder();
if(start != null && end != null){
builder.append("interactiveTime " + (end - start) + "ms");
}
if(wxNewFsRender != null){
builder.append(" wxNewFsRender " + (wxNewFsRender) + "ms");
}
return builder.toString();
}
public void updateNativePerformanceData(Map<String,String> nativePerformanceData){
if (null == nativePerformanceData){
return;
}
for (Map.Entry<String,String> entry : nativePerformanceData.entrySet()){
double value = -1;
try {
value = Double.valueOf(entry.getValue());
}catch (Exception e){
e.printStackTrace();
}
if (value != -1){
recordStatsMap.put(entry.getKey(),value);
}
}
}
}