blob: 3779727d96a17868f4e9fb63e2bc4b5c6df4edc4 [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;
import static org.apache.weex.http.WXHttpUtil.KEY_USER_AGENT;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.annotation.RestrictTo.Scope;
import android.support.annotation.WorkerThread;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import com.alibaba.fastjson.JSONObject;
import org.apache.weex.adapter.IDrawableLoader;
import org.apache.weex.adapter.IWXConfigAdapter;
import org.apache.weex.adapter.IWXHttpAdapter;
import org.apache.weex.adapter.IWXImgLoaderAdapter;
import org.apache.weex.adapter.IWXJscProcessManager;
import org.apache.weex.adapter.IWXUserTrackAdapter;
import org.apache.weex.adapter.URIAdapter;
import org.apache.weex.appfram.websocket.IWebSocketAdapter;
import org.apache.weex.bridge.EventResult;
import org.apache.weex.bridge.NativeInvokeHelper;
import org.apache.weex.bridge.SimpleJSCallback;
import org.apache.weex.bridge.WXBridgeManager;
import org.apache.weex.bridge.WXModuleManager;
import org.apache.weex.bridge.WXParams;
import org.apache.weex.common.Constants;
import org.apache.weex.common.Destroyable;
import org.apache.weex.common.OnWXScrollListener;
import org.apache.weex.common.RenderTypes;
import org.apache.weex.common.WXConfig;
import org.apache.weex.common.WXErrorCode;
import org.apache.weex.common.WXModule;
import org.apache.weex.common.WXPerformance;
import org.apache.weex.common.WXRefreshData;
import org.apache.weex.common.WXRenderStrategy;
import org.apache.weex.common.WXRequest;
import org.apache.weex.dom.WXEvent;
import org.apache.weex.http.WXHttpUtil;
import org.apache.weex.instance.InstanceOnFireEventInterceptor;
import org.apache.weex.jsEngine.JSContext;
import org.apache.weex.jsEngine.JSEngine;
import org.apache.weex.layout.ContentBoxMeasurement;
import org.apache.weex.performance.WXInstanceApm;
import org.apache.weex.performance.WXStateRecord;
import org.apache.weex.performance.WhiteScreenUtils;
import org.apache.weex.render.WXAbstractRenderContainer;
import org.apache.weex.tracing.WXTracing;
import org.apache.weex.ui.action.GraphicActionAddElement;
import org.apache.weex.ui.component.NestedContainer;
import org.apache.weex.ui.component.WXComponent;
import org.apache.weex.ui.component.WXEmbed;
import org.apache.weex.ui.flat.FlatGUIContext;
import org.apache.weex.ui.view.WXScrollView;
import org.apache.weex.utils.Trace;
import org.apache.weex.utils.WXDeviceUtils;
import org.apache.weex.utils.WXExceptionUtils;
import org.apache.weex.utils.WXFileUtils;
import org.apache.weex.utils.WXJsonUtils;
import org.apache.weex.utils.WXLogUtils;
import org.apache.weex.utils.WXReflectionUtils;
import org.apache.weex.utils.WXUtils;
import org.apache.weex.utils.WXViewUtils;
import org.apache.weex.utils.cache.RegisterCache;
import org.apache.weex.utils.tools.LogDetail;
import org.apache.weex.utils.tools.TimeCalculator;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.weex.bridge.WXBridgeManager.BundType;
/**
* Each instance of WXSDKInstance represents an running weex instance.
* It can be a pure weex view, or mixed with native view
*/
public class WXSDKInstance implements IWXActivityStateListener,View.OnLayoutChangeListener {
private static final String SOURCE_TEMPLATE_BASE64_MD5 = "templateSourceBase64MD5";
/**
* Devtool protocol
*/
public static String ACTION_DEBUG_INSTANCE_REFRESH = "DEBUG_INSTANCE_REFRESH";
public static String ACTION_INSTANCE_RELOAD = "INSTANCE_RELOAD";
//Performance
public boolean mEnd = false;
public boolean mHasCreateFinish = false;
public static final String BUNDLE_URL = "bundleUrl";
private IWXUserTrackAdapter mUserTrackAdapter;
private IWXRenderListener mRenderListener;
private IWXStatisticsListener mStatisticsListener;
/** package **/ Context mContext;
private final String mInstanceId;
private WXAbstractRenderContainer mRenderContainer;
private WXComponent mRootComp;
private boolean mRendered;
private WXRefreshData mLastRefreshData;
private NestedInstanceInterceptor mNestedInstanceInterceptor;
private String mBundleUrl = "";
public static String requestUrl = "requestUrl";
private boolean isDestroy=false;
private boolean hasException = false;
private boolean isRenderSuccess = false;
private boolean createInstanceHeartBeat = false;
private Map<String,Serializable> mUserTrackParams;
private NativeInvokeHelper mNativeInvokeHelper;
private boolean isCommit=false;
private WXGlobalEventReceiver mGlobalEventReceiver=null;
private boolean trackComponent;
private boolean enableLayerType = true;
private boolean mNeedValidate = false;
private boolean mNeedReLoad = false;
private boolean mUseScroller = false;
private int mInstanceViewPortWidth = 750;
private boolean enableFullScreenHeight = false;
private WXInstanceApm mApmForInstance;
private @NonNull
FlatGUIContext mFlatGUIContext =new FlatGUIContext();
private Map<String,String> mContainerInfo;
public boolean isNewFsEnd = false;
private List<JSONObject> componentsInfoExceedGPULimit = new LinkedList<>();
/**
* bundle type
*/
public BundType bundleType;
public long mRenderStartNanos;
public int mExecJSTraceId = WXTracing.nextId();
private boolean isViewDisAppear = false;
/**
*for network tracker
*/
public String mwxDims[] = new String [5];
public long measureTimes[] = new long [5];
public WeakReference<String> templateRef;
public Map<String,List<String>> responseHeaders = new HashMap<>();
/**
* Render strategy.
*/
private WXRenderStrategy mRenderStrategy = WXRenderStrategy.APPEND_ASYNC;
private boolean mDisableSkipFrameworkInit = false;
/**
* Render start time
*/
public long mRenderStartTime;
/**
* Refresh start time
*/
private long mRefreshStartTime;
private WXPerformance mWXPerformance;
private ScrollView mScrollView;
private WXScrollView.WXScrollViewListener mWXScrollViewListener;
private List<OnWXScrollListener> mWXScrollListeners;
private List<String> mLayerOverFlowListeners;
private List<ActionBarHandler> mWXActionbarHandlers;
private List<OnBackPressedHandler> mWXBackPressedHandlers;
private List<OnActivityResultHandler> mWXOnActivityResultHandlers;
private WXSDKInstance mParentInstance;
private String mRenderType = RenderTypes.RENDER_TYPE_NATIVE;
private boolean mPageDirty = true;
private boolean mFixMultiThreadBug = false;
public TimeCalculator mTimeCalculator;
/**
* Default Width And Viewport is 750,
* when screen width change, we adjust viewport to adapter screen change
* */
private boolean mAutoAdjustDeviceWidth = WXEnvironment.AUTO_ADJUST_ENV_DEVICE_WIDTH;
public List<JSONObject> getComponentsExceedGPULimit(){return componentsInfoExceedGPULimit;}
@RestrictTo(Scope.LIBRARY)
public void setComponentsInfoExceedGPULimit(JSONObject component){
if(component!= null && !component.isEmpty()){
componentsInfoExceedGPULimit.add(component);
}
}
public List<String> getLayerOverFlowListeners() {
return mLayerOverFlowListeners;
}
public void addLayerOverFlowListener(String ref) {
if (mLayerOverFlowListeners == null)
mLayerOverFlowListeners = new ArrayList<>();
mLayerOverFlowListeners.add(ref);
}
public void removeLayerOverFlowListener(String ref) {
if (mLayerOverFlowListeners != null)
mLayerOverFlowListeners.remove(ref);
}
/**
* whether we are in preRender mode
* */
private volatile boolean isPreRenderMode;
private boolean mCurrentGround = false;
private ComponentObserver mComponentObserver;
private Map<String, GraphicActionAddElement> inactiveAddElementAction = new ArrayMap<>();
private Map<Long, ContentBoxMeasurement> mContentBoxMeasurements = new ArrayMap<>();
private List<InstanceOnFireEventInterceptor> mInstanceOnFireEventInterceptorList;
/**
* network handler
*/
public interface ImageNetworkHandler {
public String fetchLocal(String url);
}
public interface StreamNetworkHandler {
public String fetchLocal(String url);
}
public interface CustomFontNetworkHandler {
public String fetchLocal(String url);
}
private ImageNetworkHandler mImageNetworkHandler;
private StreamNetworkHandler mStreamNetworkHandler;
private CustomFontNetworkHandler mCustomFontNetworkHandler;
public ImageNetworkHandler getImageNetworkHandler() {
return mImageNetworkHandler;
}
public void setImageNetworkHandler(ImageNetworkHandler imageNetworkHandler) {
this.mImageNetworkHandler = imageNetworkHandler;
}
public StreamNetworkHandler getStreamNetworkHandler() {
return mStreamNetworkHandler;
}
public void setStreamNetworkHandler(StreamNetworkHandler streamNetworkHandler) {
this.mStreamNetworkHandler = streamNetworkHandler;
}
public CustomFontNetworkHandler getCustomFontNetworkHandler() {
return mCustomFontNetworkHandler;
}
public void setCustomFontNetworkHandler(CustomFontNetworkHandler customFontNetworkHandler) {
this.mCustomFontNetworkHandler = customFontNetworkHandler;
}
/**
* ActionBar Handler
*/
public interface ActionBarHandler {
boolean onSupportNavigateUp();
}
public interface OnBackPressedHandler {
boolean onBackPressed();
}
public static abstract class OnActivityResultHandler {
private String id;
public OnActivityResultHandler(String id) {
this.id = id;
}
public abstract boolean onActivityResult(int requestCode, int resultCode, Intent data, String id);
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
return onActivityResult(requestCode, resultCode, data, id);
}
}
/**
* set make weexCore run in single process mode
* @param flag true means weexCore run in single process mode or multi process mode
*/
public void setUseSingleProcess(boolean flag) {
WXBridgeManager.getInstance().setUseSingleProcess(flag);
}
/**
* set open SandBox
* @param flag
*/
public void setUseSandBox(boolean flag) {
WXBridgeManager.getInstance().setSandBoxContext(flag);
}
public PriorityQueue<WXEmbed> hiddenEmbeds;
private int maxHiddenEmbedsNum = -1; //max hidden embed num, -1 standard for ulimit
public int getMaxHiddenEmbedsNum() {
return maxHiddenEmbedsNum;
}
public void setMaxHiddenEmbedsNum(int maxHiddenEmbedsNum) {
this.maxHiddenEmbedsNum = maxHiddenEmbedsNum;
}
@WorkerThread
@RestrictTo(Scope.LIBRARY)
public void addInActiveAddElementAction(String ref, GraphicActionAddElement action){
inactiveAddElementAction.put(ref, action);
}
@WorkerThread
@RestrictTo(Scope.LIBRARY)
public void removeInActiveAddElmentAction(String ref){
inactiveAddElementAction.remove(ref);
}
@WorkerThread
@RestrictTo(Scope.LIBRARY)
public GraphicActionAddElement getInActiveAddElementAction(String ref){
return inactiveAddElementAction.get(ref);
}
/**
* If anchor is created manually(etc. define a layout xml resource ),
* be aware do not add it to twice when {@link IWXRenderListener#onViewCreated(WXSDKInstance, View)}.
* @param a
*/
public void setRenderContainer(RenderContainer a){
setWXAbstractRenderContainer(a);
}
public void setWXAbstractRenderContainer(WXAbstractRenderContainer a){
if(a != null) {
a.setSDKInstance(this);
a.addOnLayoutChangeListener(this);
}
mRenderContainer = a;
if (mRenderContainer != null && mRenderContainer.getLayoutParams() != null
&& mRenderContainer.getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) {
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
WXBridgeManager.getInstance().setRenderContentWrapContentToCore(true, getInstanceId());
}
});
} else {
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
WXBridgeManager.getInstance().setRenderContentWrapContentToCore(false, getInstanceId());
}
});
}
}
private int mMaxDeepLayer;
public boolean isTrackComponent() {
return trackComponent;
}
public void setTrackComponent(boolean trackComponent) {
this.trackComponent = trackComponent;
}
/**
* Tell whether it is enabled to change the layerType
* {@link android.view.View#setLayerType(int, Paint)}
* @return True for enable to change the layerType of component, false otherwise. The default
* is True
*/
public boolean isLayerTypeEnabled() {
return enableLayerType;
}
/**
* Enable the ability of changing layerType. e.g. {@link android.view.View#setLayerType(int, Paint)}
* Disable the ability of changing layerType will have tremendous <strong>performance
* punishment</strong>.
*
* <strong>Do not</strong> set this to false unless you know exactly what you are doing.
* @param enable True for enable to change the layerType of component, false otherwise. The default
* is True
*/
public void enableLayerType(boolean enable) {
enableLayerType = enable;
}
@RestrictTo(RestrictTo.Scope.LIBRARY)
public @NonNull
FlatGUIContext getFlatUIContext(){
return mFlatGUIContext;
}
public boolean isNeedValidate() {
return mNeedValidate;
}
public boolean isNeedReLoad() {
return mNeedReLoad;
}
public void setNeedLoad(boolean load) {
mNeedReLoad = load;
}
@RestrictTo(Scope.LIBRARY)
public void setEnableFullScreenHeight(boolean fullScreenHeight){enableFullScreenHeight = fullScreenHeight;}
@RestrictTo(Scope.LIBRARY)
public boolean isFullScreenHeightEnabled(){return enableFullScreenHeight;}
public boolean isUseScroller() {
return mUseScroller;
}
public void setUseScroller(boolean use) {
mUseScroller = use;
}
public void setInstanceViewPortWidth(int instanceViewPortWidth) {
setInstanceViewPortWidth(instanceViewPortWidth,false);
}
public void setInstanceViewPortWidth(int instanceViewPortWidth,boolean fromMetaModule){
this.mInstanceViewPortWidth = instanceViewPortWidth;
this.mAutoAdjustDeviceWidth = false;
if(!fromMetaModule){
WXBridgeManager.getInstance().setViewPortWidth(getInstanceId(), mInstanceViewPortWidth);
}
}
public void resetDeviceDisplayOfPage(){
WXBridgeManager.getInstance().setDeviceDisplayOfPage(getInstanceId(), WXViewUtils.getScreenWidth(getContext()), WXViewUtils.getScreenHeight(getContext()));
}
public void setPageKeepRawCssStyles(){
WXBridgeManager.getInstance().setPageArgument(getInstanceId(),"reserveCssStyles","true");
}
public void reloadPageLayout(){
WXBridgeManager.getInstance().reloadPageLayout(getInstanceId());
}
public void setAutoAdjustDeviceWidth(boolean autoAdjustViewPort){
this.mAutoAdjustDeviceWidth = autoAdjustViewPort;
}
public boolean isAutoAdjustDeviceWidth(){
return mAutoAdjustDeviceWidth;
}
private void setDeviceDisplay(float deviceWith, float deviceHeight, float scale){
WXBridgeManager.getInstance().setDeviceDisplay(getInstanceId(), deviceWith, deviceHeight, scale);
}
public int getInstanceViewPortWidth(){
return mInstanceViewPortWidth;
}
public interface OnInstanceVisibleListener{
void onAppear();
void onDisappear();
}
private List<OnInstanceVisibleListener> mVisibleListeners = new ArrayList<>();
public WXSDKInstance(Context context) {
mInstanceId = WXSDKManager.getInstance().generateInstanceId();
init(context);
}
//for preInit
public WXSDKInstance(){
mInstanceId = WXSDKManager.getInstance().generateInstanceId();
mWXPerformance = new WXPerformance(mInstanceId);
mApmForInstance = new WXInstanceApm(mInstanceId);
WXSDKManager.getInstance().getAllInstanceMap().put(mInstanceId,this);
mTimeCalculator = new TimeCalculator(this);
initFixMultiThreadFlag();
}
private void initFixMultiThreadFlag() {
IWXConfigAdapter adapter = WXSDKManager.getInstance().getWxConfigAdapter();
if (adapter != null) {
String config = adapter.getConfig("android_weex_ext_config", "fixMultiThreadBug", "true");
mFixMultiThreadBug = Boolean.parseBoolean(config);
}
}
/**
* For unittest only.
*/
@RestrictTo(Scope.TESTS)
WXSDKInstance(Context context,String id) {
mInstanceId = id;
init(context);
}
public WXComponent getRootComponent() {
return mRootComp;
}
public void setNestedInstanceInterceptor(NestedInstanceInterceptor interceptor){
mNestedInstanceInterceptor = interceptor;
}
public final WXSDKInstance createNestedInstance(NestedContainer container){
WXSDKInstance sdkInstance = newNestedInstance();
if(mNestedInstanceInterceptor != null){
mNestedInstanceInterceptor.onCreateNestInstance(sdkInstance,container);
}
if(sdkInstance != null){
sdkInstance.setComponentObserver(this.getComponentObserver());
}
return sdkInstance;
}
protected WXSDKInstance newNestedInstance() {
return new WXSDKInstance(mContext);
}
public boolean isHasException() {
return hasException;
}
public void setHasException(boolean hasException) {
this.hasException = hasException;
}
public void createInstanceFuncHeartBeat() {
WXLogUtils.d("createInstanceFuncHeartBeat: " + mInstanceId);
this.createInstanceHeartBeat = true;
getApmForInstance().onStage(WXInstanceApm.KEY_PAGE_STAGES_END_EXCUTE_BUNDLE);
}
public void addOnInstanceVisibleListener(OnInstanceVisibleListener l){
mVisibleListeners.add(l);
}
public void removeOnInstanceVisibleListener(OnInstanceVisibleListener l){
mVisibleListeners.remove(l);
}
public void init(Context context) {
initFixMultiThreadFlag();
RegisterCache.getInstance().idle(true);
mContext = context;
mContainerInfo = new HashMap<>(4);
mNativeInvokeHelper = new NativeInvokeHelper(mInstanceId);
if (null == mWXPerformance){
mWXPerformance = new WXPerformance(mInstanceId);
}
if (null == mApmForInstance){
mApmForInstance = new WXInstanceApm(mInstanceId);
}
mWXPerformance.WXSDKVersion = WXEnvironment.WXSDK_VERSION;
mWXPerformance.JSLibInitTime = WXEnvironment.sJSLibInitTime;
mUserTrackAdapter=WXSDKManager.getInstance().getIWXUserTrackAdapter();
WXSDKManager.getInstance().getAllInstanceMap().put(mInstanceId,this);
mContainerInfo.put(WXInstanceApm.KEY_PAGE_PROPERTIES_CONTAINER_NAME, context instanceof Activity
? context.getClass().getSimpleName()
:"unKnowContainer"
);
mContainerInfo.put(WXInstanceApm.KEY_PAGE_PROPERTIES_INSTANCE_TYPE,"page");
// WXBridgeManager.getInstance().checkJsEngineMultiThread();
mDisableSkipFrameworkInit = isDisableSkipFrameworkInDataRender();
if(mTimeCalculator == null) {
mTimeCalculator = new TimeCalculator(this);
}
}
/**
* Set a Observer for component.
* This observer will be called in each component, should not doing
* anything will impact render performance.
*
* @param observer
*/
public void setComponentObserver(ComponentObserver observer){
mComponentObserver = observer;
}
public ComponentObserver getComponentObserver(){
return mComponentObserver;
}
public NativeInvokeHelper getNativeInvokeHelper() {
return mNativeInvokeHelper;
}
@Deprecated
public void setBizType(String bizType) {
if (!TextUtils.isEmpty(bizType)) {
mWXPerformance.bizType = bizType;
}
}
public ScrollView getScrollView() {
return mScrollView;
}
public void setRootScrollView(ScrollView scrollView) {
mScrollView = scrollView;
if (mWXScrollViewListener != null && mScrollView instanceof WXScrollView) {
((WXScrollView) mScrollView).addScrollViewListener(mWXScrollViewListener);
}
}
@Deprecated
public void registerScrollViewListener(WXScrollView.WXScrollViewListener scrollViewListener) {
mWXScrollViewListener = scrollViewListener;
}
@Deprecated
public WXScrollView.WXScrollViewListener getScrollViewListener() {
return mWXScrollViewListener;
}
@Deprecated
public void setIWXUserTrackAdapter(IWXUserTrackAdapter adapter) {
}
public void setContainerInfo(String key,String val){
mContainerInfo.put(key,val);
}
public Map<String, String> getContainerInfo() {
return mContainerInfo;
}
/**
* Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
* @param template bundle js
* @param options os iphone/android/ipad
* weexversion Weex version(like 1.0.0)
* appversion App version(like 1.0.0)
* devid Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
* sysversion Device system version(like 5.4.4、7.0.4, should be used with os)
* sysmodel Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
* Time UNIX timestamp, UTC+08:00
* TTID(Optional)
* MarkertId
* Appname(Optional) tm,tb,qa
* Bundleurl(Optional) template url
* @param jsonInitData Initial data for rendering
*/
public void render(String template, Map<String, Object> options, String jsonInitData) {
render(template, options, jsonInitData, WXRenderStrategy.APPEND_ASYNC);
}
/**
* Render template asynchronously
* @param template bundle js
* @param options os iphone/android/ipad
* weexversion Weex version(like 1.0.0)
* appversion App version(like 1.0.0)
* devid Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
* sysversion Device system version(like 5.4.4、7.0.4, should be used with os)
* sysmodel Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
* Time UNIX timestamp, UTC+08:00
* TTID(Optional)
* MarkertId
* Appname(Optional) tm,tb,qa
* Bundleurl(Optional) template url
* @param jsonInitData Initial data for rendering
* @param flag RenderStrategy {@link WXRenderStrategy}
*/
@Deprecated
public void render(String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
render(WXPerformance.DEFAULT, template, options, jsonInitData, flag);
}
/**
* Render template asynchronously
*
* @param pageName, used for performance log.
* @param template bundle js
* @param options os iphone/android/ipad
* weexversion Weex version(like 1.0.0)
* appversion App version(like 1.0.0)
* devid Device id(like Aqh9z8dRJNBhmS9drLG5BKCmXhecHUXIZoXOctKwFebH)
* sysversion Device system version(like 5.4.4、7.0.4, should be used with os)
* sysmodel Device model(like iOS:"MGA82J/A", android:"MI NOTE LTE")
* Time UNIX timestamp, UTC+08:00
* TTID(Optional)
* MarkertId
* Appname(Optional) tm,tb,qa
* Bundleurl(Optional) template url
* @param jsonInitData Initial data for rendering
* @param flag RenderStrategy {@link WXRenderStrategy}
*/
public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
render(pageName, new Script(template), options, jsonInitData, flag);
}
public void render(String pageName, Script template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag) {
mWXPerformance.beforeInstanceRender(mInstanceId);
if(WXEnvironment.isApkDebugable() && WXPerformance.DEFAULT.equals(pageName)){
if (getUIContext() != null) {
new AlertDialog.Builder(getUIContext())
.setTitle("Error: Missing pageName")
.setMessage("We highly recommend you to set pageName. Call" +
"\nWXSDKInstance#render(String pageName, String template, Map<String, Object> options, String jsonInitData, WXRenderStrategy flag)\n" +
"to fix it.")
.show();
}
return;
}
renderInternal(pageName,template,options,jsonInitData,flag);
}
/**
* Render binary template asynchronously in DATA_RENDER_BINARY strategy.
*/
public void render(String pageName, byte[] template, Map<String, Object> options, String jsonInitData) {
render(pageName, new Script(template), options, jsonInitData, WXRenderStrategy.DATA_RENDER_BINARY);
}
private void ensureRenderArchor(){
if(mRenderContainer == null){
if (getContext() != null) {
setRenderContainer(new RenderContainer(getContext()));
mRenderContainer.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
mRenderContainer.setBackgroundColor(Color.TRANSPARENT);
mRenderContainer.setSDKInstance(this);
mRenderContainer.addOnLayoutChangeListener(this);
}
}
}
private void renderInternal(String pageName,
String template,
Map<String, Object> options,
String jsonInitData,
WXRenderStrategy flag) {
if (mRendered || TextUtils.isEmpty(template)) {
return;
}
renderInternal(pageName, new Script(template), options, jsonInitData, flag);
}
private boolean isPreInit = false;
public boolean isPreInitMode(){
return isPreInit;
}
private boolean isPreDownLoad =false;
public boolean isPreDownLoad(){
return isPreDownLoad;
}
public void onInstanceReady(){
WXLogUtils.d("test->","onInstanceReady");
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_CONTAINER_READY);
if (!isPreInit && !isPreDownLoad){
return;
}
mApmForInstance.onInstanceReady(isPreDownLoad);
if (isPreDownLoad){
mHttpListener.onInstanceReady();
}
}
public void preInit(String pageName,
String script,
Map<String, Object> options,
String jsonInitData,
WXRenderStrategy flag){
isPreInit = true;
mRenderStrategy = flag;
Map<String, Object> renderOptions = options;
if (renderOptions == null) {
renderOptions = new HashMap<>();
}
//mApmForInstance.doInit();
mApmForInstance.isReady = false;
WXSDKManager.getInstance().createInstance(this, new Script(script), renderOptions, jsonInitData);
}
public void preDownLoad(String url,
Map<String, Object> options,
String jsonInitData,
WXRenderStrategy flag){
this.isPreDownLoad =true;
mRenderStrategy = flag;
mApmForInstance.isReady = false;
renderByUrl(url,url,options,jsonInitData,flag);
}
private void renderInternal(String pageName,
Script template,
Map<String, Object> options,
String jsonInitData,
WXRenderStrategy flag){
if (mRendered || template == null || template.isEmpty()) {
return;
}
LogDetail logDetail = mTimeCalculator.createLogDetail("renderInternal");
mRenderStrategy = flag;
//some case ,from render(template),but not render (url)
if (!mApmForInstance.hasInit()){
mApmForInstance.doInit();
}
mApmForInstance.setPageName(pageName);
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_RENDER_ORGIGIN);
mApmForInstance.doDelayCollectData();
mWXPerformance.pageName = (TextUtils.isEmpty(pageName) ? "defaultBundleUrl":pageName);
if (TextUtils.isEmpty(mBundleUrl)) {
mBundleUrl = mWXPerformance.pageName;
}
if (WXTracing.isAvailable()) {
WXTracing.TraceEvent traceEvent = WXTracing.newEvent("executeBundleJS", mInstanceId, -1);
traceEvent.traceId = mExecJSTraceId;
traceEvent.iid = mInstanceId;
traceEvent.tname = "JSThread";
traceEvent.ph = "B";
traceEvent.submit();
mRenderStartNanos = System.nanoTime();
}
ensureRenderArchor();
Map<String, Object> renderOptions = options;
if (renderOptions == null) {
renderOptions = new HashMap<>();
}
if (WXEnvironment.sDynamicMode && !TextUtils.isEmpty(WXEnvironment.sDynamicUrl) && renderOptions.get("dynamicMode") == null) {
renderOptions.put("dynamicMode", "true");
renderByUrl(pageName, WXEnvironment.sDynamicUrl, renderOptions, jsonInitData, flag);
return;
}
TimeCalculator timeCalculator = new TimeCalculator(this);
mWXPerformance.JSTemplateSize = template.length() / 1024f;
mApmForInstance.addStats(WXInstanceApm.KEY_PAGE_STATS_BUNDLE_SIZE,mWXPerformance.JSTemplateSize);
mRenderStartTime = System.currentTimeMillis();
WXSDKManager.getInstance().setCrashInfo(WXEnvironment.WEEX_CURRENT_KEY,pageName);
if(mAutoAdjustDeviceWidth && WXDeviceUtils.isAutoResize(mContext)){
if(WXEnvironment.AUTO_UPDATE_APPLICATION_SCREEN_SIZE) {
WXViewUtils.updateApplicationScreen(mContext);
}
WXParams params = WXBridgeManager.getInstance().getInitParams();
if(params != null && !TextUtils.equals(params.getDeviceWidth(), String.valueOf(WXViewUtils.getScreenWidth(mContext)))){
params.setDeviceWidth(String.valueOf(WXViewUtils.getScreenWidth(mContext)));
params.setDeviceHeight(String.valueOf(WXViewUtils.getScreenHeight(mContext)));
float density = WXEnvironment.sApplication.getResources().getDisplayMetrics().density;
WXEnvironment.addCustomOptions(WXConfig.scale, Float.toString(density));
String statusBarHeight = null;
if(WXViewUtils.getStatusBarHeight(mContext) > 0 ){
statusBarHeight = String.valueOf(WXViewUtils.getStatusBarHeight(mContext));
}
WXBridgeManager.getInstance().updateInitDeviceParams(params.getDeviceWidth(),
params.getDeviceHeight(),
Float.toString(density), statusBarHeight);
setDeviceDisplay(WXViewUtils.getScreenWidth(mContext),
WXViewUtils.getScreenHeight(mContext),
WXViewUtils.getScreenDensity(mContext));
}
}
logDetail.taskStart();
if (isPreInitMode()){
getApmForInstance().onStage(WXInstanceApm.KEY_PAGE_STAGES_LOAD_BUNDLE_START);
WXBridgeManager.getInstance().loadJsBundleInPreInitMode(getInstanceId(),template.getContent());
} else {
WXSDKManager.getInstance().createInstance(this, template, renderOptions, jsonInitData);
}
logDetail.taskEnd();
mRendered = true;
final IWXJscProcessManager wxJscProcessManager = WXSDKManager.getInstance().getWXJscProcessManager();
if(wxJscProcessManager != null && wxJscProcessManager.shouldReboot()) {
WXSDKManager.getInstance().postOnUiThread(new Runnable() {
@Override
public void run() {
checkWhiteScreen();
if(isDestroy || hasException || isRenderSuccess) {
return;
}
// there is no need to reboot js engine if render by eagle
if(isDataRender()) {
return;
}
View containerView = getContainerView();
if(containerView instanceof ViewGroup) {
if(0 == ((ViewGroup) containerView).getChildCount()) {
if(wxJscProcessManager.withException(WXSDKInstance.this)) {
onJSException(String.valueOf(WXErrorCode.WX_ERR_RELOAD_PAGE),"jsc reboot","jsc reboot");
}
if(!createInstanceHeartBeat) {
WXBridgeManager.getInstance().callReportCrashReloadPage(mInstanceId, null);
WXLogUtils.e("callReportCrashReloadPage with jsc reboot");
}
}
}
}
}, wxJscProcessManager.rebootTimeout());
}
}
private void checkWhiteScreen(){
if (isDestroy ||!WhiteScreenUtils.doWhiteScreenCheck()){
return;
}
boolean isWS = WhiteScreenUtils.isWhiteScreen(this);
if (!isWS){
return;
}
WXErrorCode errorCode = createInstanceHeartBeat?WXErrorCode.WX_ERROR_WHITE_SCREEN:WXErrorCode.WHITE_SCREEN_RESPONSE_TIMEOUT;
if (WXBridgeManager.getInstance().isRebootExceedLimit()){
errorCode = WXErrorCode.WHITE_SCREEN_REBOOT_EXCEED_LIMIT;
}
Map<String,String> args = new HashMap<>(1);
String vieTreeMsg = WhiteScreenUtils.takeViewTreeSnapShot(this);
args.put("viewTree",null == vieTreeMsg?"null viewTreeMsg":vieTreeMsg);
args.put("weexCoreThreadStackTrace",WXBridgeManager.getInstance().getWeexCoreThreadStackTrace());
for (Map.Entry<String,String> entry: WXStateRecord.getInstance().getStateInfo().entrySet()){
args.put(entry.getKey(),entry.getValue());
}
WXExceptionUtils.commitCriticalExceptionRT(getInstanceId(),errorCode,"checkEmptyScreen",errorCode.getErrorMsg(),args);
}
public boolean skipFrameworkInit(){
return isDataRender() && !mDisableSkipFrameworkInit;
}
private boolean isDataRender() {
return getRenderStrategy() == WXRenderStrategy.DATA_RENDER_BINARY || getRenderStrategy() == WXRenderStrategy.DATA_RENDER;
}
private void renderByUrlInternal(String pageName,
final String url,
Map<String, Object> options,
final String jsonInitData,
WXRenderStrategy flag) {
LogDetail logDetail = mTimeCalculator.createLogDetail("renderByUrlInternal");
logDetail.taskStart();
ensureRenderArchor();
pageName = wrapPageName(pageName, url);
mBundleUrl = url;
mRenderStrategy = flag;
if(WXSDKManager.getInstance().getValidateProcessor()!=null) {
mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
}
Map<String, Object> renderOptions = options;
if (renderOptions == null) {
renderOptions = new HashMap<>();
}
if (!renderOptions.containsKey(BUNDLE_URL)) {
renderOptions.put(BUNDLE_URL, url);
}
getWXPerformance().pageName = pageName;
mApmForInstance.doInit();
mApmForInstance.setPageName(pageName);
Uri uri = Uri.parse(url);
if (uri != null && TextUtils.equals(uri.getScheme(), "file")) {
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_START);
String template = WXFileUtils.loadFileOrAsset(assembleFilePath(uri), mContext);
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_END);
render(pageName,template , renderOptions, jsonInitData, flag);
return;
}
boolean is_wlasm = false;
if (uri != null && uri.getPath()!=null) {
if(uri.getPath().endsWith(".wlasm")){
is_wlasm = true;
}
}
if (is_wlasm){
flag = WXRenderStrategy.DATA_RENDER_BINARY;
}
IWXHttpAdapter adapter = WXSDKManager.getInstance().getIWXHttpAdapter();
WXRequest wxRequest = new WXRequest();
wxRequest.url = rewriteUri(Uri.parse(url), URIAdapter.BUNDLE).toString();
if(wxRequest != null && !TextUtils.isEmpty(wxRequest.url)){
requestUrl = wxRequest.url;
}else {
requestUrl = pageName;
}
if (wxRequest.paramMap == null) {
wxRequest.paramMap = new HashMap<String, String>();
}
wxRequest.instanceId = getInstanceId();
wxRequest.paramMap.put(KEY_USER_AGENT, WXHttpUtil.assembleUserAgent(mContext,WXEnvironment.getConfig()));
wxRequest.paramMap.put("isBundleRequest","true");
mHttpListener = new WXHttpListener(this, pageName, renderOptions, jsonInitData, flag, System.currentTimeMillis());
mHttpListener.isPreDownLoadMode = isPreDownLoad;
mHttpListener.setSDKInstance(this);
mApmForInstance.onStage(WXInstanceApm.KEY_PAGE_STAGES_DOWN_BUNDLE_START);
adapter.sendRequest(wxRequest, (IWXHttpAdapter.OnHttpListener) mHttpListener);
logDetail.taskEnd();
}
private WXHttpListener mHttpListener = null;
/**
* Use {@link #render(String, String, Map, String, WXRenderStrategy)} instead.
* @param pageName
* @param template
* @param options
* @param jsonInitData
* @param width
* @param height
* @param flag
*/
@Deprecated
public void render(String pageName, String template, Map<String, Object> options, String jsonInitData, int width, int height, WXRenderStrategy flag) {
render(pageName,template,options,jsonInitData,flag);
}
/**
* Render template asynchronously, use {@link WXRenderStrategy#APPEND_ASYNC} as render strategy
* @param template bundle js
*/
public void render(String template) {
render(WXPerformance.DEFAULT, template, null, null, mRenderStrategy);
}
/**
* Use {@link #render(String)} instead.
* @param template
* @param width
* @param height
*/
@Deprecated
public void render(String template, int width, int height) {
render(template);
}
/**
* Use {@link #renderByUrl(String, String, Map, String, WXRenderStrategy)} instead.
* @param pageName
* @param url
* @param options
* @param jsonInitData
* @param width
* @param height
* @param flag
*/
@Deprecated
public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final int width, final int height, final WXRenderStrategy flag){
renderByUrl(pageName,url,options,jsonInitData,flag);
}
public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final WXRenderStrategy flag) {
renderByUrlInternal(pageName,url,options,jsonInitData,flag);
}
private String wrapPageName(String pageName, String url) {
if(TextUtils.equals(pageName, WXPerformance.DEFAULT)){
pageName = url;
WXExceptionUtils.degradeUrl = pageName;
try {
Uri uri=Uri.parse(url);
if(uri!=null){
Uri.Builder builder=new Uri.Builder();
builder.scheme(uri.getScheme());
builder.authority(uri.getAuthority());
builder.path(uri.getPath());
pageName=builder.toString();
}
} catch (Exception e) {
}
}
return pageName;
}
private String assembleFilePath(Uri uri) {
if(uri!=null && uri.getPath()!=null){
return uri.getPath().replaceFirst("/","");
}
return "";
}
public void reloadPage(boolean reloadThis) {
WXSDKEngine.reload();
if (reloadThis) {
if (mContext != null) {
Intent intent = new Intent();
intent.setAction(ACTION_INSTANCE_RELOAD);
intent.putExtra("url", mBundleUrl);
mContext.sendBroadcast(intent);
}
// mRendered = false;
// destroy();
// renderInternal(mPackage, mTemplate, mOptions, mJsonInitData, mFlag);
// refreshInstance("{}");
} else {
IWXConfigAdapter adapter = WXSDKManager.getInstance().getWxConfigAdapter();
if (adapter != null) {
boolean degrade = Boolean.parseBoolean(adapter
.getConfig("android_weex_ext_config",
"degrade_to_h5_if_not_reload",
"true"));
WXLogUtils.e("degrade : " + degrade);
if(degrade) {
onJSException(String.valueOf(WXErrorCode.WX_ERR_RELOAD_PAGE.getErrorCode()),"Do not reloadPage", "Do not reloadPage degradeToH5");
WXLogUtils.e("Do not reloadPage degradeToH5");
}
}
}
}
/**
* Refresh instance asynchronously.
* @param data the new data
*/
public void refreshInstance(Map<String, Object> data) {
if (data == null) {
return;
}
refreshInstance(WXJsonUtils.fromObjectToJSONString(data));
}
/**
* Refresh instance asynchronously.
* @param jsonData the new data
*/
public void refreshInstance(String jsonData) {
if (jsonData == null) {
return;
}
mRefreshStartTime = System.currentTimeMillis();
//cancel last refresh message
if (mLastRefreshData != null) {
mLastRefreshData.isDirty = true;
}
mLastRefreshData = new WXRefreshData(jsonData, false);
WXSDKManager.getInstance().refreshInstance(mInstanceId, mLastRefreshData);
}
public WXRenderStrategy getRenderStrategy() {
return mRenderStrategy;
}
public Context getUIContext() {
return mContext;
}
public String getInstanceId() {
return mInstanceId;
}
public Context getContext() {
return mContext;
}
public int getWeexHeight() {
return mRenderContainer == null ? 0: mRenderContainer.getHeight();
}
public int getWeexWidth() {
return mRenderContainer == null ? 0: mRenderContainer.getWidth();
}
public IWXImgLoaderAdapter getImgLoaderAdapter() {
return WXSDKManager.getInstance().getIWXImgLoaderAdapter();
}
public IDrawableLoader getDrawableLoader() {
return WXSDKManager.getInstance().getDrawableLoader();
}
public URIAdapter getURIAdapter(){
return WXSDKManager.getInstance().getURIAdapter();
}
public Uri rewriteUri(Uri uri,String type){
return getURIAdapter().rewrite(this,type,uri);
}
public IWXHttpAdapter getWXHttpAdapter() {
return WXSDKManager.getInstance().getIWXHttpAdapter();
}
public IWXStatisticsListener getWXStatisticsListener() {
return mStatisticsListener;
}
public @Nullable
IWebSocketAdapter getWXWebSocketAdapter() {
return WXSDKManager.getInstance().getIWXWebSocketAdapter();
}
@Deprecated
public void reloadImages() {
if (mScrollView == null) {
return;
}
}
public boolean isPreRenderMode() {
return this.isPreRenderMode;
}
public void setPreRenderMode(final boolean isPreRenderMode) {
WXSDKManager.getInstance().getWXRenderManager().postOnUiThread(new Runnable() {
@Override
public void run() {
WXSDKInstance.this.isPreRenderMode = isPreRenderMode;
}
},0);
}
public void setContext(@NonNull Context context) {
this.mContext = context;
}
/********************************
* begin register listener
********************************************************/
public void registerRenderListener(IWXRenderListener listener) {
mRenderListener = listener;
}
@Deprecated
public void registerActivityStateListener(IWXActivityStateListener listener) {
}
public void registerStatisticsListener(IWXStatisticsListener listener) {
mStatisticsListener = listener;
}
/**set render start time*/
public void setRenderStartTime(long renderStartTime) {
this.mRenderStartTime = renderStartTime;
}
/********************************
* end register listener
********************************************************/
/********************************
* begin hook Activity life cycle callback
********************************************************/
@Override
public void onActivityCreate() {
// module listen Activity onActivityCreate
WXModuleManager.onActivityCreate(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityCreate();
}else{
if (WXEnvironment.isApkDebugable()){
WXLogUtils.w("Warning :Component tree has not build completely,onActivityCreate can not be call!");
}
}
mGlobalEventReceiver=new WXGlobalEventReceiver(this);
try {
getContext().registerReceiver(mGlobalEventReceiver, new IntentFilter(WXGlobalEventReceiver.EVENT_ACTION));
} catch (Throwable e) {
// Huawei may throw a exception if register more than 500 BroadcastReceivers
WXLogUtils.e(e.getMessage());
mGlobalEventReceiver = null;
}
}
@Override
public void onActivityStart() {
// module listen Activity onActivityCreate
WXModuleManager.onActivityStart(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityStart();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
}
}
}
public boolean onCreateOptionsMenu(Menu menu) {
WXModuleManager.onCreateOptionsMenu(getInstanceId(),menu);
if(mRootComp != null) {
mRootComp.onCreateOptionsMenu(menu);
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely,onActivityStart can not be call!");
}
}
return true;
}
@Override
public void onActivityPause() {
onViewDisappear();
if(!isCommit){
if(mUseScroller){
mWXPerformance.useScroller=1;
}
mWXPerformance.maxDeepViewLayer=getMaxDeepLayer();
mWXPerformance.wxDims = mwxDims;
mWXPerformance.measureTimes = measureTimes;
if (mUserTrackAdapter != null) {
mUserTrackAdapter.commit(mContext, null, IWXUserTrackAdapter.LOAD, mWXPerformance, getUserTrackParams());
}
isCommit=true;
}
// module listen Activity onActivityPause
WXModuleManager.onActivityPause(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityPause();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely,onActivityPause can not be call!");
}
}
if (!mCurrentGround) {
WXLogUtils.i("Application to be in the backround");
Intent intent = new Intent(WXGlobalEventReceiver.EVENT_ACTION);
intent.putExtra(WXGlobalEventReceiver.EVENT_NAME, Constants.Event.PAUSE_EVENT);
intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID, getInstanceId());
/**
* Fix NPE just like {@link #onActivityResume()}
*/
if (null != mContext){
mContext.sendBroadcast(intent);
}else {
try {
WXEnvironment.getApplication().sendBroadcast(intent);
} catch (Exception e){
WXLogUtils.e("weex",e);
}
}
this.mCurrentGround = true;
}
//component appear
if((WXEnvironment.isApkDebugable() || WXEnvironment.isPerf()) && mApmForInstance != null){
WXLogUtils.e("PerformanceData " + mApmForInstance.toPerfString());
}
}
@Override
public void onActivityResume() {
// notify onActivityResume callback to module
WXModuleManager.onActivityResume(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityResume();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely, onActivityResume can not be call!");
}
}
if (mCurrentGround) {
WXLogUtils.i("Application to be in the foreground");
Intent intent = new Intent(WXGlobalEventReceiver.EVENT_ACTION);
intent.putExtra(WXGlobalEventReceiver.EVENT_NAME, Constants.Event.RESUME_EVENT);
intent.putExtra(WXGlobalEventReceiver.EVENT_WX_INSTANCEID, getInstanceId());
//todo tmp solution for gray version
if (null != mContext){
mContext.sendBroadcast(intent);
}else {
WXEnvironment.getApplication().sendBroadcast(intent);
}
this.mCurrentGround = false;
}
onViewAppear();
}
@Override
public void onActivityStop() {
// notify onActivityResume callback to module
WXModuleManager.onActivityStop(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityStop();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely, onActivityStop can not be call!");
}
}
}
@Override
public void onActivityDestroy() {
WXModuleManager.onActivityDestroy(getInstanceId());
if(mRootComp != null) {
mRootComp.onActivityDestroy();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely, onActivityDestroy can not be call!");
}
}
this.mTimeCalculator.println();
destroy();
}
@Override
public boolean onActivityBack() {
WXModuleManager.onActivityBack(getInstanceId());
if(mRootComp != null) {
return mRootComp.onActivityBack();
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely, onActivityBack can not be call!");
}
}
return false;
}
public boolean onSupportNavigateUp() {
if (mWXActionbarHandlers != null) {
for (ActionBarHandler handler : mWXActionbarHandlers) {
if (handler.onSupportNavigateUp()) {
return true;
}
}
}
return false;
}
public boolean onBackPressed() {
if(mWXBackPressedHandlers != null) {
for (OnBackPressedHandler handler : mWXBackPressedHandlers) {
if(handler.onBackPressed()) {
return true;
}
}
}
WXComponent comp = getRootComponent();
if(comp != null) {
WXEvent events= comp.getEvents();
boolean hasNativeBackHook = events.contains(Constants.Event.NATIVE_BACK);
if (hasNativeBackHook) {
EventResult result = comp.fireEventWait(Constants.Event.NATIVE_BACK, null);
if (WXUtils.getBoolean(result.getResult(), false)) {
return true;
}
}
boolean hasBackPressed = events.contains(Constants.Event.CLICKBACKITEM);
if (hasBackPressed) {
fireEvent(comp.getRef(), Constants.Event.CLICKBACKITEM,null, null);
}
return hasBackPressed;
}
return false;
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
WXModuleManager.onActivityResult(getInstanceId(),requestCode,resultCode,data);
if(mRootComp != null) {
mRootComp.onActivityResult(requestCode,resultCode,data);
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w("Warning :Component tree has not build completely, onActivityResult can not be call!");
}
}
if (mWXOnActivityResultHandlers != null && !mWXOnActivityResultHandlers.isEmpty()) {
for (OnActivityResultHandler onActivityResultHandler : mWXOnActivityResultHandlers) {
if (onActivityResultHandler.onActivityResult(requestCode, resultCode, data)) {
break;
}
}
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
WXModuleManager.onRequestPermissionsResult(getInstanceId(),requestCode,permissions,grantResults);
if(mRootComp != null) {
mRootComp.onRequestPermissionsResult(requestCode,permissions,grantResults);
}else{
if (WXEnvironment.isApkDebugable()) {
WXLogUtils.w(
"Warning :Component tree has not build completely, onRequestPermissionsResult can not be call!");
}
}
}
/********************************
* end hook Activity life cycle callback
********************************************************/
public void onViewDisappear(){
isViewDisAppear = false;
mApmForInstance.onDisAppear();
WXComponent comp = getRootComponent();
if(comp != null) {
fireEvent(comp.getRef(), Constants.Event.VIEWDISAPPEAR, null, null);
//call disappear of nested instances
for(OnInstanceVisibleListener instance:mVisibleListeners){
instance.onDisappear();
}
}
}
public boolean isViewDisAppear(){
return isViewDisAppear;
}
public void onViewAppear(){
isViewDisAppear = true;
mApmForInstance.onAppear();
WXComponent comp = getRootComponent();
if(comp != null) {
fireEvent( comp.getRef(), Constants.Event.VIEWAPPEAR,null, null);
for(OnInstanceVisibleListener instance:mVisibleListeners){
instance.onAppear();
}
}
}
public void onCreateFinish() {
if(mHasCreateFinish){
return;
}
if (mContext != null) {
onViewAppear();
View wxView= mRenderContainer;
if(mRenderListener != null) {
mRenderListener.onViewCreated(WXSDKInstance.this, wxView);
}
if (mStatisticsListener != null) {
mStatisticsListener.onFirstView();
}
}
}
/**
* call back when update finish
*/
public void onUpdateFinish() {
if (WXEnvironment.isApkDebugable()){
WXLogUtils.d("Instance onUpdateSuccess");
}
}
public void runOnUiThread(Runnable action) {
WXSDKManager.getInstance().postOnUiThread(action, 0);
}
public void onRenderSuccess(final int width, final int height) {
isRenderSuccess = true;
if (!isNewFsEnd){
getApmForInstance().arriveNewFsRenderTime();
}
if (!getApmForInstance().stageMap.containsKey(WXInstanceApm.KEY_PAGE_STAGES_INTERACTION)){
getApmForInstance().arriveInteraction(getRootComponent());
}
long time = System.currentTimeMillis() - mRenderStartTime;
long[] renderFinishTime = WXBridgeManager.getInstance().getRenderFinishTime(getInstanceId());
mWXPerformance.callBridgeTime = renderFinishTime[0];
mWXPerformance.cssLayoutTime = renderFinishTime[1];
mWXPerformance.parseJsonTime = renderFinishTime[2];
mWXPerformance.totalTime = time;
if(mWXPerformance.screenRenderTime<0.001){
mWXPerformance.screenRenderTime = time;
}
if (mRenderListener != null && mContext != null) {
mRenderListener.onRenderSuccess(WXSDKInstance.this, width, height);
if (mUserTrackAdapter != null) {
WXPerformance performance=new WXPerformance(mInstanceId);
performance.errCode=WXErrorCode.WX_SUCCESS.getErrorCode();
performance.args=getBundleUrl();
mUserTrackAdapter.commit(mContext,null,IWXUserTrackAdapter.JS_BRIDGE,performance,getUserTrackParams());
}
if (WXEnvironment.isApkDebugable()){
WXLogUtils.d(WXLogUtils.WEEX_PERF_TAG, mWXPerformance.toString());
}
}
if(WXEnvironment.isPerf()){
WXLogUtils.e("weex_perf",mWXPerformance.getPerfData());
}
}
public void onRefreshSuccess(final int width, final int height) {
if (mRenderListener != null && mContext != null) {
mRenderListener.onRefreshSuccess(WXSDKInstance.this, width, height);
}
}
public void onChangeElement(WXComponent component, boolean isOutOfScreen) {
if (isDestroy() || null == mRenderContainer || mWXPerformance == null ){
return;
}
if (null == component || component.isIgnoreInteraction){
return;
}
if (mRenderContainer.hasConsumeEvent()) {
return;
}
long lastElementChangeTime = System.currentTimeMillis();
long lazyLoadTime;
if (mHasCreateFinish){
lazyLoadTime = lastElementChangeTime - mWXPerformance.renderTimeOrigin;
if (lazyLoadTime > 8000) {
//force record detail performance data
return;
}
}
if (component.mIsAddElementToTree) {
getWXPerformance().localInteractionViewAddCount++;
if (!isOutOfScreen)
getWXPerformance().interactionViewAddLimitCount++;
component.mIsAddElementToTree = false;
}
if (!isOutOfScreen) {
mApmForInstance.arriveInteraction(component);
}
}
public void onRenderError(final String errCode, final String msg) {
WXStateRecord.getInstance().recordException(getInstanceId(),"onRenderError,"+errCode+","+msg);
if (mRenderListener != null && mContext != null) {
WXLogUtils.e("onRenderError "+errCode +","+msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mRenderListener != null && mContext != null) {
mRenderListener.onException(WXSDKInstance.this, errCode, msg);
}
}
});
}
}
public void onJSException(final String errCode, final String function, final String exception) {
WXStateRecord.getInstance().recordException(getInstanceId(),"onJSException,"+errCode+","+function+"|"+exception);
hasException = true;
if (mRenderListener != null && mContext != null) {
WXLogUtils.e("onJSException "+errCode +","+exception);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mRenderListener != null && mContext != null) {
StringBuilder builder = new StringBuilder();
builder.append(function);
builder.append(exception);
mRenderListener.onException(WXSDKInstance.this, errCode, builder.toString());
}
}
});
}
}
@Override
public final void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int
oldTop, int oldRight, int oldBottom) {
if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
onLayoutChange(v);
}
}
/**
* Subclass should override this method to get notifications of layout change of GodView.
* @param godView the godView.
*/
public void onLayoutChange(View godView) {
}
private boolean mCreateInstance =true;
public void firstScreenCreateInstanceTime(long time) {
if(mCreateInstance) {
mWXPerformance.firstScreenJSFExecuteTime = time -mRenderStartTime;
mCreateInstance =false;
}
}
public void callJsTime(final long time){
if (!mEnd){
mWXPerformance.fsCallJsTotalTime+=time;
mWXPerformance.fsCallJsTotalNum++;
}
}
public void onComponentCreate(WXComponent component,long createTime) {
mWXPerformance.mActionAddElementCount++;
mWXPerformance.mActionAddElementSumTime += createTime;
if (!mEnd){
mWXPerformance.fsComponentCreateTime+=createTime;
mWXPerformance.fsComponentCount++;
}
mWXPerformance.componentCount++;
mWXPerformance.componentCreateTime+=createTime;
}
public void callActionAddElementTime(long time) {
mWXPerformance.mActionAddElementSumTime += time;
}
public void onOldFsRenderTimeLogic(){
if (mEnd){
return;
}
mEnd = true;
if (mStatisticsListener != null && mContext != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mStatisticsListener != null && mContext != null) {
Trace.beginSection("onFirstScreen");
mStatisticsListener.onFirstScreen();
Trace.endSection();
}
}
});
}
mApmForInstance.arriveFSRenderTime();
mWXPerformance.fsRenderTime = System.currentTimeMillis();
mWXPerformance.screenRenderTime = System.currentTimeMillis() - mRenderStartTime;
}
public WXSDKInstance getParentInstance() {
return mParentInstance;
}
public void setParentInstance(WXSDKInstance mParentInstance) {
this.mParentInstance = mParentInstance;
}
private void destroyView(View rootView) {
try {
if (rootView instanceof ViewGroup) {
ViewGroup cViewGroup = ((ViewGroup) rootView);
for (int index = 0; index < cViewGroup.getChildCount(); index++) {
destroyView(cViewGroup.getChildAt(index));
}
cViewGroup.removeViews(0, ((ViewGroup) rootView).getChildCount());
// Ensure that the viewgroup's status to be normal
WXReflectionUtils.setValue(rootView, "mChildrenCount", 0);
}
if(rootView instanceof Destroyable){
((Destroyable)rootView).destroy();
}
} catch (Exception e) {
WXLogUtils.e("WXSDKInstance destroyView Exception: ", e);
}
}
public synchronized void destroy() {
if(!isDestroy()) {
if(mParentInstance != null){
mParentInstance = null;
}
mApmForInstance.onEnd();
if(mRendered) {
WXSDKManager.getInstance().destroyInstance(mInstanceId);
}
try {
if (mGlobalEventReceiver != null) {
getContext().unregisterReceiver(mGlobalEventReceiver);
mGlobalEventReceiver = null;
}
}catch (IllegalArgumentException e){
WXLogUtils.w(WXLogUtils.getStackTrace(e));
}
if (mRootComp != null) {
mRootComp.destroy();
mRootComp = null;
}
if(mRenderContainer != null){
destroyView(mRenderContainer);
}
if (mGlobalEvents != null) {
mGlobalEvents.clear();
}
if (mComponentObserver != null) {
mComponentObserver = null;
}
if (mLayerOverFlowListeners != null) {
mLayerOverFlowListeners.clear();
}
if(mWXOnActivityResultHandlers != null && !mWXOnActivityResultHandlers.isEmpty()) {
mWXOnActivityResultHandlers.clear();
}
if(mWXBackPressedHandlers != null && !mWXBackPressedHandlers.isEmpty()) {
mWXBackPressedHandlers.clear();
}
if(mWXActionbarHandlers != null && !mWXActionbarHandlers.isEmpty()) {
mWXActionbarHandlers.clear();
}
getFlatUIContext().destroy();
mFlatGUIContext = null;
mInstanceOnFireEventInterceptorList = null;
mWXScrollListeners = null;
mWXActionbarHandlers = null;
mWXBackPressedHandlers = null;
mRenderContainer = null;
mNestedInstanceInterceptor = null;
mUserTrackAdapter = null;
mScrollView = null;
mContext = null;
mRenderListener = null;
isDestroy = true;
mStatisticsListener = null;
if(responseHeaders != null){
responseHeaders.clear();
}
if(templateRef != null){
templateRef = null;
}
if (null != mContentBoxMeasurements) {
mContentBoxMeasurements.clear();
}
mWXPerformance.afterInstanceDestroy(mInstanceId);
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
WXBridgeManager.getInstance().onInstanceClose(getInstanceId());
inactiveAddElementAction.clear();
}
});
//when report error in @WXExceptionUtils
// instance may had destroy and remove,
// so we delay remove from allInstanceMap
WXBridgeManager.getInstance().postDelay(new Runnable() {
@Override
public void run() {
WXSDKManager.getInstance().getAllInstanceMap().remove(mInstanceId);
}
},1000);
}
}
public boolean isDestroy(){
return isDestroy;
}
/**
* @return If you use render () the return value may be empty
*/
public @Nullable String getBundleUrl() {
return mBundleUrl;
}
public View getRootView() {
if (mRootComp == null)
return null;
return mRootComp.getRealView();
}
public View getContainerView() {
return mRenderContainer;
}
@Deprecated
public void setBundleUrl(String url){
mBundleUrl = url;
if(WXSDKManager.getInstance().getValidateProcessor()!=null) {
mNeedValidate = WXSDKManager.getInstance().getValidateProcessor().needValidate(mBundleUrl);
}
}
public void onRootCreated(WXComponent root) {
this.mRootComp = root;
this.mRootComp.mDeepInComponentTree =1;
mRenderContainer.addView(root.getHostView());
setSize(mRenderContainer.getWidth(),mRenderContainer.getHeight());
}
/**
* Move fixed view to container ,except it's already moved.
* @param fixedChild
*/
public void moveFixedView(View fixedChild){
if(mRenderContainer != null) {
ViewGroup parent;
if((parent = (ViewGroup) fixedChild.getParent()) != null){
if (parent != mRenderContainer) {
parent.removeView(fixedChild);
mRenderContainer.addView(fixedChild);
}
}else{
mRenderContainer.addView(fixedChild);
}
}
}
public void removeFixedView(View fixedChild){
if(mRenderContainer != null) {
mRenderContainer.removeView(fixedChild);
}
}
public int getRenderContainerPaddingLeft() {
if(mRenderContainer != null) {
return mRenderContainer.getPaddingLeft();
}
return 0;
}
public int getRenderContainerPaddingRight() {
if(mRenderContainer != null) {
return mRenderContainer.getPaddingRight();
}
return 0;
}
public int getRenderContainerPaddingTop() {
if(mRenderContainer != null) {
return mRenderContainer.getPaddingTop();
}
return 0;
}
public synchronized List<OnWXScrollListener> getWXScrollListeners() {
return mWXScrollListeners;
}
public synchronized void registerOnWXScrollListener(OnWXScrollListener wxScrollListener) {
if(mWXScrollListeners==null){
mWXScrollListeners=new ArrayList<>();
}
mWXScrollListeners.add(wxScrollListener);
}
public synchronized void registerActionbarHandler(ActionBarHandler actionBarHandler) {
if(actionBarHandler == null) {
return;
}
if(mWXActionbarHandlers == null) {
mWXActionbarHandlers = new ArrayList<>();
}
mWXActionbarHandlers.add(actionBarHandler);
}
public synchronized void unRegisterActionbarHandler(ActionBarHandler actionBarHandler) {
if(mWXActionbarHandlers != null && actionBarHandler != null) {
mWXActionbarHandlers.remove(actionBarHandler);
}
}
public synchronized void unRegisterOnActivityResultHandler(OnActivityResultHandler onActivityResultHandler) {
if(mWXOnActivityResultHandlers != null && onActivityResultHandler != null) {
mWXOnActivityResultHandlers.remove(onActivityResultHandler);
}
}
public synchronized void registerOnActivityResultHandler(OnActivityResultHandler onActivityResultHandler) {
if(onActivityResultHandler == null) {
return;
}
if(mWXOnActivityResultHandlers == null) {
mWXOnActivityResultHandlers = new ArrayList<>();
}
mWXOnActivityResultHandlers.add(onActivityResultHandler);
}
public synchronized void registerBackPressedHandler(OnBackPressedHandler backPressedHandler) {
if(backPressedHandler == null) {
return;
}
if(mWXBackPressedHandlers == null) {
mWXBackPressedHandlers = new ArrayList<>();
}
mWXBackPressedHandlers.add(backPressedHandler);
}
public synchronized void unRegisterBackPressedHandler(OnBackPressedHandler backPressedHandler) {
if(mWXBackPressedHandlers != null && backPressedHandler != null) {
mWXBackPressedHandlers.remove(backPressedHandler);
}
}
static int sScreenHeight = -1;
public void setSize(int width, int height) {
if (width > 0 && height > 0 & !isDestroy && mRendered && mRenderContainer != null) {
if (sScreenHeight < 0){
sScreenHeight = WXViewUtils.getScreenHeight(getContext());
}
if (sScreenHeight>0){
double screenRatio = (double)height/(double)sScreenHeight *100;
if(screenRatio>100){
screenRatio =100;
}
getApmForInstance().addStats(WXInstanceApm.KEY_PAGE_STATS_BODY_RATIO,screenRatio);
}
ViewGroup.LayoutParams layoutParams = mRenderContainer.getLayoutParams();
if (layoutParams != null) {
final float realWidth = width;
final float realHeight = height;
if (mRenderContainer.getWidth() != width || mRenderContainer.getHeight() != height) {
layoutParams.width = width;
layoutParams.height = height;
mRenderContainer.setLayoutParams(layoutParams);
}
if (mRootComp != null && layoutParams != null) {
final boolean isWidthWrapContent = layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT;
final boolean isHeightWrapContent = layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT;
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
WXBridgeManager.getInstance().setDefaultRootSize(getInstanceId(), realWidth, realHeight, isWidthWrapContent,
isHeightWrapContent);
}
});
}
}
}
}
/*Global Event*/
private HashMap<String, List<String>> mGlobalEvents = new HashMap<>();
public void fireGlobalEventCallback(String eventName, Map<String,Object> params){
List<String> callbacks=mGlobalEvents.get(eventName);
if(callbacks!=null){
for(String callback:callbacks){
WXSDKManager.getInstance().callback(mInstanceId,callback,params,true);
}
}
}
/**
* Fire event callback on a element.
* @param elementRef
* @param type
* @param data
* @param domChanges
*/
public void fireEvent(String elementRef,final String type, final Map<String, Object> data,final Map<String, Object> domChanges, List<Object> eventArgs){
fireEvent(elementRef, type, data, domChanges, eventArgs, null);
}
public void fireEvent(String elementRef,final String type, final Map<String, Object> data,final Map<String, Object> domChanges, List<Object> eventArgs, EventResult callback) {
onInterceptInstanceEvent(getInstanceId(), elementRef, type, data, domChanges);
if (null != mWXPerformance && mWXPerformance.fsCallEventTotalNum<Integer.MAX_VALUE){
mWXPerformance.fsCallEventTotalNum++;
}
mApmForInstance.updateFSDiffStats(WXInstanceApm.KEY_PAGE_STATS_FS_CALL_EVENT_NUM,1);
WXBridgeManager.getInstance().fireEventOnNode(getInstanceId(),elementRef,type,data,domChanges, eventArgs, callback);
}
/**
* Fire event callback on a element.
* @param elementRef
* @param type
* @param data
* @param domChanges
*/
public void fireEvent(String elementRef,final String type, final Map<String, Object> data,final Map<String, Object> domChanges){
fireEvent(elementRef, type, data, domChanges, null);
}
public void fireEvent(String elementRef,final String type, final Map<String, Object> data){
fireEvent(elementRef,type,data,null);
}
public void fireEvent(String ref, String type){
fireEvent(ref,type,new HashMap<String, Object>());
}
protected void addEventListener(String eventName, String callback) {
if (TextUtils.isEmpty(eventName) || TextUtils.isEmpty(callback)) {
return;
}
List<String> callbacks = mGlobalEvents.get(eventName);
if (callbacks == null) {
callbacks = new ArrayList<>();
mGlobalEvents.put(eventName, callbacks);
}
callbacks.add(callback);
}
protected void removeEventListener(String eventName, String callback) {
if (TextUtils.isEmpty(eventName) || TextUtils.isEmpty(callback)) {
return;
}
List<String> callbacks = mGlobalEvents.get(eventName);
if (callbacks != null) {
callbacks.remove(callback);
}
}
protected void removeEventListener(String eventName) {
if (TextUtils.isEmpty(eventName)) {
return;
}
mGlobalEvents.remove(eventName);
}
/**
* Notifies WEEX that this event has occurred
* @param eventName WEEX register event
* @param module Events occur in this Module
* @param params The parameters to be notified to WEEX are required
*/
public void fireModuleEvent(String eventName, WXModule module,Map<String, Object> params) {
if (TextUtils.isEmpty(eventName) || module == null) {
return;
}
Map<String, Object> event = new HashMap<>();
event.put("type", eventName);
event.put("module", module.getModuleName());
event.put("data", params);
List<String> callbacks = module.getEventCallbacks(eventName);
if (callbacks != null) {
for (String callback : callbacks) {
SimpleJSCallback jsCallback = new SimpleJSCallback(mInstanceId, callback);
if (module.isOnce(callback)) {
jsCallback.invoke(event);
} else {
jsCallback.invokeAndKeepAlive(event);
}
}
}
}
/**
* Check whether the current module registered the event
* @param eventName EventName register in weex
* @param module Events occur in this Module
* @return register->true
*/
public boolean checkModuleEventRegistered(String eventName,WXModule module) {
if (module != null) {
List<String> events = module.getEventCallbacks(eventName);
if (events != null && events.size() > 0) {
return true;
}
}
return false;
}
public WXPerformance getWXPerformance(){
return mWXPerformance;
}
public WXInstanceApm getApmForInstance() {
return mApmForInstance;
}
public Map<String, Serializable> getUserTrackParams() {
return mUserTrackParams;
}
public void addUserTrackParameter(String key,Serializable value){
if(this.mUserTrackParams == null){
this.mUserTrackParams = new ConcurrentHashMap<>();
}
mUserTrackParams.put(key,value);
}
public void clearUserTrackParameters(){
if(this.mUserTrackParams != null){
this.mUserTrackParams.clear();
}
}
public void removeUserTrackParameter(String key){
if(this.mUserTrackParams != null){
this.mUserTrackParams.remove(key);
}
}
public int getMaxDeepLayer() {
return mMaxDeepLayer;
}
public void setMaxDeepLayer(int maxDeepLayer) {
mMaxDeepLayer = maxDeepLayer;
mApmForInstance.updateMaxStats(WXInstanceApm.KEY_PAGE_STATS_MAX_DEEP_VIEW,maxDeepLayer);
}
public void setMaxDomDeep(int maxDomDeep){
mApmForInstance.updateMaxStats(WXInstanceApm.KEY_PAGE_STATS_MAX_DEEP_DOM,maxDomDeep);
if (null == mWXPerformance){
return;
}
if (mWXPerformance.maxDeepVDomLayer <= maxDomDeep){
mWXPerformance.maxDeepVDomLayer = maxDomDeep;
}
}
public void onHttpStart(){
if (!mEnd){
mWXPerformance.fsRequestNum++;
}
}
/**
* return md5, and bytes length
* */
public String getTemplateInfo() {
String template = getTemplate();
if(template == null){
return " template md5 null ,httpHeader:" + JSONObject.toJSONString(responseHeaders);
}
if(TextUtils.isEmpty(template)){
return " template md5 length 0 ,httpHeader" + JSONObject.toJSONString(responseHeaders);
}
try {
byte[] bts = template.getBytes("UTF-8");
String sourceMD5 = WXFileUtils.md5(bts);
String sourceBase64MD5 = WXFileUtils.base64Md5(bts);
ArrayList<String> sourceMD5List = new ArrayList<>();
ArrayList<String> sourceBase64MD5List = new ArrayList<>();
sourceMD5List.add(sourceMD5);
sourceBase64MD5List.add(sourceBase64MD5);
responseHeaders.put("templateSourceMD5", sourceMD5List);
responseHeaders.put(SOURCE_TEMPLATE_BASE64_MD5, sourceBase64MD5List);
return " template md5 " + sourceMD5 + " length " + bts.length
+ " base64 md5 " + sourceBase64MD5
+ " response header " + JSONObject.toJSONString(responseHeaders);
} catch (Exception e) {
return "template md5 getBytes error";
}
}
/**
* check template header md5 match with header content-md5
* */
public boolean isContentMd5Match(){
if(responseHeaders == null){
return true;
}
List<String> contentMD5s = responseHeaders.get("Content-Md5");
if(contentMD5s == null){
contentMD5s = responseHeaders.get("content-md5");
}
if(contentMD5s == null || contentMD5s.size() <= 0){
return true;
}
String md5 = contentMD5s.get(0);
List<String> sourceBase64Md5 = responseHeaders.get(SOURCE_TEMPLATE_BASE64_MD5);
if(sourceBase64Md5 == null){
getTemplateInfo();
sourceBase64Md5 = responseHeaders.get(SOURCE_TEMPLATE_BASE64_MD5);
}
if(sourceBase64Md5 == null || sourceBase64Md5.size() == 0){
return true;
}
return md5.equals(sourceBase64Md5.get(0));
}
public String getTemplate() {
if(templateRef == null){
return null;
}
return templateRef.get();
}
public void setTemplate(String template) {
this.templateRef = new WeakReference<String>(template);
}
public interface NestedInstanceInterceptor {
void onCreateNestInstance(WXSDKInstance instance, NestedContainer container);
}
public void OnVSync() {
if(mFixMultiThreadBug) {
if(!mPageDirty) {
return;
}
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
boolean forceLayout = WXBridgeManager.getInstance().notifyLayout(getInstanceId());
if(forceLayout) {
WXBridgeManager.getInstance().forceLayout(getInstanceId());
}
}
});
} else {
boolean forceLayout = WXBridgeManager.getInstance().notifyLayout(getInstanceId());
if(forceLayout) {
WXBridgeManager.getInstance().post(new Runnable() {
@Override
public void run() {
WXBridgeManager.getInstance().forceLayout(getInstanceId());
}
});
}
}
}
public void addContentBoxMeasurement(long renderObjectPtr, ContentBoxMeasurement contentBoxMeasurement) {
mContentBoxMeasurements.put(renderObjectPtr, contentBoxMeasurement);
}
public ContentBoxMeasurement getContentBoxMeasurement(long renderObjectPtr) {
return mContentBoxMeasurements.get(renderObjectPtr);
}
private void onInterceptInstanceEvent(String instanceId, String elementRef, String type, Map<String, Object> data, Map<String, Object> domChanges) {
if(this.mInstanceOnFireEventInterceptorList == null){
return;
}
for(InstanceOnFireEventInterceptor instanceOnFireEventInterceptor : this.mInstanceOnFireEventInterceptorList){
instanceOnFireEventInterceptor.onInterceptFireEvent(instanceId, elementRef, type, data, domChanges);
}
}
public List<InstanceOnFireEventInterceptor> getInstanceOnFireEventInterceptorList(){
if(this.mInstanceOnFireEventInterceptorList == null){
this.mInstanceOnFireEventInterceptorList = new ArrayList<>();
}
return mInstanceOnFireEventInterceptorList;
}
public void addInstanceOnFireEventInterceptor(InstanceOnFireEventInterceptor instanceOnFireEventInterceptor) {
if(instanceOnFireEventInterceptor == null){
return;
}
if(!getInstanceOnFireEventInterceptorList().contains(instanceOnFireEventInterceptor)){
getInstanceOnFireEventInterceptorList().add(instanceOnFireEventInterceptor);
}
}
public String getRenderType() {
return mRenderType;
}
public void setRenderType(String renderType) {
this.mRenderType = renderType;
}
private static boolean isDisableSkipFrameworkInDataRender() {
IWXConfigAdapter adapter = WXSDKManager.getInstance().getWxConfigAdapter();
if (adapter == null) {
return false;
}
String result = adapter.getConfig("wxeagle", "disable_skip_framework_init", "false");
return "true".equals(result);
}
public boolean isPageDirty() {
return mPageDirty;
}
public void setPageDirty(boolean mPageDirty) {
this.mPageDirty = mPageDirty;
}
}