http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/dom/transition/WXTransition.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/transition/WXTransition.java b/android/sdk/src/main/java/com/taobao/weex/dom/transition/WXTransition.java index 8c32c71..e59c4f7 100644 --- a/android/sdk/src/main/java/com/taobao/weex/dom/transition/WXTransition.java +++ b/android/sdk/src/main/java/com/taobao/weex/dom/transition/WXTransition.java @@ -32,13 +32,16 @@ import android.text.TextUtils; import android.util.Property; import android.view.View; import android.view.animation.Interpolator; + import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXSDKManager; +import com.taobao.weex.bridge.WXBridgeManager; import com.taobao.weex.common.Constants; -import com.taobao.weex.dom.DOMActionContext; -import com.taobao.weex.dom.WXDomHandler; -import com.taobao.weex.dom.WXDomObject; -import com.taobao.weex.dom.flex.Spacing; +//import com.taobao.weex.dom.DOMActionContext; +//import com.taobao.weex.dom.WXDomHandler; +//import com.taobao.weex.dom.WXDomObject; +//import com.taobao.weex.dom.flex.Spacing; +import com.taobao.weex.dom.CSSShorthand; import com.taobao.weex.ui.animation.BackgroundColorProperty; import com.taobao.weex.ui.animation.TransformParser; import com.taobao.weex.ui.component.WXComponent; @@ -117,7 +120,7 @@ public class WXTransition { private Interpolator interpolator; private long duration; private long delay; - private WXDomObject domObject; + private WXComponent mWXComponent; private Handler handler; private ValueAnimator layoutValueAnimator; private Map<String, Object> layoutPendingUpdates; @@ -142,7 +145,7 @@ public class WXTransition { /** * create transition from map styles if style contains transitionProperty * */ - public static WXTransition fromMap(Map<String, Object> style, WXDomObject domObject){ + public static WXTransition fromMap(Map<String, Object> style, WXComponent component){ if(style.get(TRANSITION_PROPERTY) == null){ return null; } @@ -158,11 +161,10 @@ public class WXTransition { transition.duration = parseTimeMillis(style, TRANSITION_DURATION, 0); transition.delay = parseTimeMillis(style, TRANSITION_DELAY, 0); transition.interpolator = createTimeInterpolator(WXUtils.getString(style.get(TRANSITION_TIMING_FUNCTION), null)); - transition.domObject = domObject; + transition.mWXComponent = component; return transition; } - /** * check updates has transition property * */ @@ -177,23 +179,23 @@ public class WXTransition { public void updateTranstionParams(Map<String, Object> updates){ if(updates.containsKey(TRANSITION_DELAY)){ - domObject.getStyles().put(TRANSITION_DELAY, updates.remove(TRANSITION_DELAY)); - this.delay = parseTimeMillis(domObject.getStyles(), TRANSITION_DELAY, 0); + mWXComponent.getStyles().put(TRANSITION_DELAY, updates.remove(TRANSITION_DELAY)); + this.delay = parseTimeMillis(mWXComponent.getStyles(), TRANSITION_DELAY, 0); } if(updates.containsKey(TRANSITION_TIMING_FUNCTION) && updates.get(TRANSITION_TIMING_FUNCTION) != null){ - domObject.getStyles().put(TRANSITION_TIMING_FUNCTION, updates.remove(TRANSITION_TIMING_FUNCTION)); - this.interpolator = createTimeInterpolator(domObject.getStyles().get(TRANSITION_TIMING_FUNCTION).toString()); + mWXComponent.getStyles().put(TRANSITION_TIMING_FUNCTION, updates.remove(TRANSITION_TIMING_FUNCTION)); + this.interpolator = createTimeInterpolator(mWXComponent.getStyles().get(TRANSITION_TIMING_FUNCTION).toString()); } if(updates.containsKey(TRANSITION_DURATION)){ - domObject.getStyles().put(TRANSITION_DURATION, updates.remove(TRANSITION_DURATION)); - this.duration = parseTimeMillis(domObject.getStyles(), TRANSITION_DURATION, 0); + mWXComponent.getStyles().put(TRANSITION_DURATION, updates.remove(TRANSITION_DURATION)); + this.duration = parseTimeMillis(mWXComponent.getStyles(), TRANSITION_DURATION, 0); } if(updates.containsKey(TRANSITION_PROPERTY)){ - domObject.getStyles().put(TRANSITION_PROPERTY, updates.remove(TRANSITION_PROPERTY)); - updateTransitionProperties(this, WXUtils.getString(domObject.getStyles().get(TRANSITION_PROPERTY), null)); + mWXComponent.getStyles().put(TRANSITION_PROPERTY, updates.remove(TRANSITION_PROPERTY)); + updateTransitionProperties(this, WXUtils.getString(mWXComponent.getStyles().get(TRANSITION_PROPERTY), null)); } } @@ -219,7 +221,7 @@ public class WXTransition { } } - int delay = WXUtils.getNumberInt(domObject.getAttrs().get("actionDelay"), 16); + int delay = WXUtils.getNumberInt(mWXComponent.getAttrs().get("actionDelay"), 16); if(delay > duration){ delay = (int) duration; } @@ -268,12 +270,12 @@ public class WXTransition { if(targetStyles.containsKey(property)){ //reset pre transition style Object targetValue = targetStyles.remove(property); - domObject.getStyles().put(property, targetValue); - WXComponent component = getComponent(); - if(component != null - && component.getDomObject() != null){ - component.getDomObject().getStyles().put(property, targetValue); - } + mWXComponent.getStyles().put(property, targetValue); +// domObject.getStyles().put(property, targetValue); +// WXComponent component = getComponent(); +// if(component != null && component.getDomObject() != null){ +// component.getDomObject().getStyles().put(property, targetValue); +// } } } } @@ -292,9 +294,8 @@ public class WXTransition { if(duration < Float.MIN_NORMAL){ return; } - WXComponent component = getComponent(); - if(component != null && domObject.getEvents().contains(Constants.Event.ON_TRANSITION_END)){ - component.fireEvent(Constants.Event.ON_TRANSITION_END); + if(mWXComponent != null && mWXComponent.getEvents().contains(Constants.Event.ON_TRANSITION_END)){ + mWXComponent.fireEvent(Constants.Event.ON_TRANSITION_END); } } }; @@ -335,7 +336,7 @@ public class WXTransition { List<PropertyValuesHolder> holders = new ArrayList<>(8); String transform = WXUtils.getString(transformPendingUpdates.remove(Constants.Name.TRANSFORM), null); if(!TextUtils.isEmpty(transform)){ - Map<Property<View,Float>, Float> properties = TransformParser.parseTransForm(transform, (int)domObject.getLayoutWidth(), (int)domObject.getLayoutHeight(), domObject.getViewPortWidth()); + Map<Property<View,Float>, Float> properties = TransformParser.parseTransForm(transform, (int)mWXComponent.getLayoutWidth(), (int)mWXComponent.getLayoutHeight(), mWXComponent.getViewPortWidth()); PropertyValuesHolder[] transformHolders = TransformParser.toHolders(properties); for(PropertyValuesHolder holder : transformHolders){ holders.add(holder); @@ -363,7 +364,7 @@ public class WXTransition { } break; case Constants.Name.BACKGROUND_COLOR:{ - int fromColor = WXResourceUtils.getColor(WXUtils.getString(domObject.getStyles().getBackgroundColor(), null), 0); + int fromColor = WXResourceUtils.getColor(WXUtils.getString(mWXComponent.getStyles().getBackgroundColor(), null), 0); int toColor = WXResourceUtils.getColor(WXUtils.getString(value, null), 0); if(WXViewUtils.getBorderDrawable(taregtView) != null){ fromColor = WXViewUtils.getBorderDrawable(taregtView).getColor(); @@ -403,9 +404,6 @@ public class WXTransition { } super.onAnimationEnd(animation); WXTransition.this.onTransitionAnimationEnd(); - if(WXEnvironment.isApkDebugable()){ - WXLogUtils.d("WXTransition transform onTransitionAnimationEnd " + domObject.getRef()); - } } }); transformAnimator.start(); @@ -444,73 +442,73 @@ public class WXTransition { PropertyValuesHolder holder = null; switch (property){ case Constants.Name.WIDTH:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.WIDTH, domObject.getLayoutWidth(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloat(value, 0.0f), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.WIDTH, mWXComponent.getLayoutWidth(), + WXViewUtils.getRealPxByWidth(WXUtils.getFloat(value, 0.0f), mWXComponent.getViewPortWidth())); } break; case Constants.Name.HEIGHT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.HEIGHT, domObject.getLayoutHeight(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloat(value, 0.0f), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.HEIGHT, mWXComponent.getLayoutHeight(), + WXViewUtils.getRealPxByWidth(WXUtils.getFloat(value, 0.0f), mWXComponent.getViewPortWidth())); } break; case Constants.Name.MARGIN_TOP:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_TOP, domObject.getMargin().get(Spacing.TOP), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_TOP, mWXComponent.getMargin().get(CSSShorthand.EDGE.TOP), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.MARGIN_LEFT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_LEFT, domObject.getMargin().get(Spacing.LEFT), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_LEFT, mWXComponent.getMargin().get(CSSShorthand.EDGE.LEFT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.MARGIN_RIGHT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_RIGHT, domObject.getMargin().get(Spacing.RIGHT), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_RIGHT, mWXComponent.getMargin().get(CSSShorthand.EDGE.RIGHT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.MARGIN_BOTTOM:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_BOTTOM, domObject.getMargin().get(Spacing.BOTTOM), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.MARGIN_BOTTOM, mWXComponent.getMargin().get(CSSShorthand.EDGE.BOTTOM), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.LEFT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.LEFT, domObject.getPositionLeft(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.LEFT, mWXComponent.getPadding().get(CSSShorthand.EDGE.LEFT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.RIGHT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.RIGHT, domObject.getPositionRight(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.RIGHT, mWXComponent.getPadding().get(CSSShorthand.EDGE.RIGHT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.BOTTOM:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.BOTTOM, domObject.getPositionBottom(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.BOTTOM, mWXComponent.getPadding().get(CSSShorthand.EDGE.BOTTOM), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.TOP:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.TOP, domObject.getPositionTop(), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.TOP, mWXComponent.getPadding().get(CSSShorthand.EDGE.TOP), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.PADDING_TOP:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_TOP, domObject.getPadding().get(Spacing.TOP), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_TOP, mWXComponent.getPadding().get(CSSShorthand.EDGE.TOP), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.PADDING_BOTTOM:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_BOTTOM, domObject.getPadding().get(Spacing.BOTTOM), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_BOTTOM, mWXComponent.getPadding().get(CSSShorthand.EDGE.BOTTOM), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.PADDING_LEFT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_LEFT, domObject.getPadding().get(Spacing.LEFT), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_LEFT, mWXComponent.getPadding().get(CSSShorthand.EDGE.LEFT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; case Constants.Name.PADDING_RIGHT:{ - holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_RIGHT, domObject.getPadding().get(Spacing.RIGHT), - WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, domObject.getViewPortWidth()), domObject.getViewPortWidth())); + holder = PropertyValuesHolder.ofFloat(Constants.Name.PADDING_RIGHT, mWXComponent.getPadding().get(CSSShorthand.EDGE.RIGHT), + WXViewUtils.getRealPxByWidth(WXUtils.getFloatByViewport(value, mWXComponent.getViewPortWidth()), mWXComponent.getViewPortWidth())); } break; default: @@ -526,22 +524,14 @@ public class WXTransition { layoutValueAnimator = ValueAnimator.ofPropertyValuesHolder(holders); layoutValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override - public void onAnimationUpdate(ValueAnimator animation) { + public void onAnimationUpdate(final ValueAnimator animation) { PropertyValuesHolder holders[] = animation.getValues(); for(PropertyValuesHolder holder : holders){ - String property = holder.getPropertyName(); - updateShadowLayoutPropertyByName(domObject,property,(Float)animation.getAnimatedValue(property)); - } - DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(domObject.getDomContext().getInstanceId()); - if(domActionContext == null){ - return; - } - domActionContext.markDirty(); - WXSDKManager.getInstance().getWXDomManager().sendEmptyMessageDelayed(WXDomHandler.MsgType.WX_DOM_TRANSITION_BATCH, 0); - if(WXEnvironment.isApkDebugable()){ - WXLogUtils.d("WXTransition send layout batch msg"); + final String property = holder.getPropertyName(); + asynchronouslyUpdateLayout(mWXComponent, property, (Float) animation.getAnimatedValue(property)); } +// WXBridgeManager.getInstance().calculateLayoutPostToJSThread(mWXComponent.getInstanceId(), mWXComponent.getRef(), false); } }); layoutValueAnimator.addListener(new AnimatorListenerAdapter() { @@ -559,9 +549,6 @@ public class WXTransition { return; } super.onAnimationEnd(animation); - if(WXEnvironment.isApkDebugable()){ - WXLogUtils.d("WXTransition layout onTransitionAnimationEnd " + domObject.getRef()); - } WXTransition.this.onTransitionAnimationEnd(); } }); @@ -573,89 +560,82 @@ public class WXTransition { layoutValueAnimator.start(); } - private static void updateShadowLayoutPropertyByName(WXDomObject domObject, String propertyName, float propertyValue) { - if(domObject == null || TextUtils.isEmpty(propertyName)) { - return; - } - switch (propertyName){ - case Constants.Name.WIDTH:{ - domObject.setStyleWidth(propertyValue); - } - break; - case Constants.Name.HEIGHT:{ - domObject.setStyleHeight(propertyValue); - } - break; - case Constants.Name.MARGIN_TOP:{ - domObject.setMargin(Spacing.TOP, propertyValue); - } - break; - case Constants.Name.MARGIN_LEFT:{ - domObject.setMargin(Spacing.LEFT, propertyValue); - } - break; - case Constants.Name.MARGIN_RIGHT:{ - domObject.setMargin(Spacing.RIGHT, propertyValue); - } - break; - case Constants.Name.MARGIN_BOTTOM:{ - domObject.setMargin(Spacing.BOTTOM, propertyValue); - } - break; - case Constants.Name.LEFT:{ - domObject.setPositionLeft(propertyValue); - } - break; - case Constants.Name.RIGHT:{ - domObject.setPositionRight(propertyValue); - } - break; - case Constants.Name.BOTTOM:{ - domObject.setPositionBottom(propertyValue); - } - break; - case Constants.Name.TOP:{ - domObject.setPositionTop(propertyValue); - } - break; - case Constants.Name.PADDING_TOP:{ - domObject.setPadding(Spacing.TOP, propertyValue); - } - break; - case Constants.Name.PADDING_BOTTOM:{ - domObject.setPadding(Spacing.BOTTOM, propertyValue); - } - break; - case Constants.Name.PADDING_LEFT:{ - domObject.setPadding(Spacing.LEFT, propertyValue); - } - break; - case Constants.Name.PADDING_RIGHT:{ - domObject.setPadding(Spacing.RIGHT, propertyValue); - } - break; - default: - break; - } - } - @SuppressWarnings("unused") - public static void asynchronouslyUpdateLayout(WXComponent component, String propertyName, float propertyValue) { - if(component == null || TextUtils.isEmpty(propertyName)) { - return; - } - String instanceId = component.getInstanceId(); - DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(instanceId); - if(domActionContext == null){ + public static void asynchronouslyUpdateLayout(WXComponent component, final String propertyName, final float propertyValue) { + if(component == null) { return; } - WXDomObject domObject = domActionContext.getDomByRef(component.getRef()); - if(domObject == null || TextUtils.isEmpty(instanceId)) { + final String ref = component.getRef(); + final String instanceId = component.getInstanceId(); + if(TextUtils.isEmpty(ref) || TextUtils.isEmpty(instanceId)) { return; } - updateShadowLayoutPropertyByName(domObject, propertyName, propertyValue); - domActionContext.markDirty(); - WXSDKManager.getInstance().getWXDomManager().sendEmptyMessageDelayed(WXDomHandler.MsgType.WX_DOM_TRANSITION_BATCH, 0); + + WXSDKManager.getInstance().getWXBridgeManager().post(new Runnable() { + @Override + public void run() { + switch (propertyName){ + case Constants.Name.WIDTH:{ + WXBridgeManager.getInstance().setStyleWidth(instanceId, ref, propertyValue); + } + break; + case Constants.Name.HEIGHT:{ + WXBridgeManager.getInstance().setStyleHeight(instanceId, ref, propertyValue); + } + break; + case Constants.Name.MARGIN_TOP:{ + WXBridgeManager.getInstance().setMargin(instanceId, ref, CSSShorthand.EDGE.TOP, propertyValue); + } + break; + case Constants.Name.MARGIN_LEFT:{ + WXBridgeManager.getInstance().setMargin(instanceId, ref, CSSShorthand.EDGE.LEFT, propertyValue); + } + break; + case Constants.Name.MARGIN_RIGHT:{ + WXBridgeManager.getInstance().setMargin(instanceId, ref, CSSShorthand.EDGE.RIGHT, propertyValue); + } + break; + case Constants.Name.MARGIN_BOTTOM:{ + WXBridgeManager.getInstance().setMargin(instanceId, ref, CSSShorthand.EDGE.BOTTOM, propertyValue); + } + break; + case Constants.Name.LEFT:{ + WXBridgeManager.getInstance().setPosition(instanceId, ref, CSSShorthand.EDGE.LEFT, propertyValue); + } + break; + case Constants.Name.RIGHT:{ + WXBridgeManager.getInstance().setPosition(instanceId, ref, CSSShorthand.EDGE.RIGHT, (propertyValue)); + } + break; + case Constants.Name.BOTTOM:{ + WXBridgeManager.getInstance().setPosition(instanceId, ref, CSSShorthand.EDGE.BOTTOM, propertyValue); + } + break; + case Constants.Name.TOP:{ + WXBridgeManager.getInstance().setPosition(instanceId, ref, CSSShorthand.EDGE.TOP, propertyValue); + } + break; + case Constants.Name.PADDING_TOP:{ + WXBridgeManager.getInstance().setPadding(instanceId, ref, CSSShorthand.EDGE.TOP, propertyValue); + } + break; + case Constants.Name.PADDING_BOTTOM:{ + WXBridgeManager.getInstance().setPadding(instanceId, ref, CSSShorthand.EDGE.BOTTOM, propertyValue); + } + break; + case Constants.Name.PADDING_LEFT:{ + WXBridgeManager.getInstance().setPadding(instanceId, ref, CSSShorthand.EDGE.LEFT, propertyValue); + } + break; + case Constants.Name.PADDING_RIGHT:{ + WXBridgeManager.getInstance().setPadding(instanceId, ref, CSSShorthand.EDGE.RIGHT, propertyValue); + } + break; + default: + break; + } + } + }); } private synchronized void onTransitionAnimationEnd(){ @@ -670,14 +650,10 @@ public class WXTransition { } synchronized (targetStyles){ if(targetStyles.size() > 0){ - WXComponent component = getComponent(); for(String property : properties) { if(targetStyles.containsKey(property)){ Object targetValue = targetStyles.remove(property); - domObject.getStyles().put(property, targetValue); - if(component != null && component.getDomObject() != null){ - component.getDomObject().getStyles().put(property, targetValue); - } + mWXComponent.getStyles().put(property, targetValue); } } targetStyles.clear(); @@ -685,33 +661,11 @@ public class WXTransition { } } - private WXComponent getComponent(){ - DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(domObject.getDomContext().getInstanceId()); - if(domActionContext != null){ - WXComponent component = domActionContext.getCompByRef(domObject.getRef()); - return component; - } - return null; - } - - private View getTargetView(){ - if(domObject.getDomContext() == null){ - return null; - } - DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(domObject.getDomContext().getInstanceId()); - if(domActionContext != null){ - WXComponent component = domActionContext.getCompByRef(domObject.getRef()); - if(component != null && component.getHostView() != null) { - return component.getHostView(); - } - } - return null; + return null != mWXComponent ? mWXComponent.getHostView() : null; } - - /** * get time millis * */ @@ -794,4 +748,7 @@ public class WXTransition { } } + public List<String> getProperties() { + return properties; + } }
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java index a8de759..d0bcb7e 100644 --- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java +++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java @@ -18,11 +18,7 @@ */ package com.taobao.weex.el.parse; -import com.taobao.weex.WXEnvironment; -import com.taobao.weex.ui.component.list.template.CellRenderContext; - import java.lang.reflect.Array; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -66,12 +62,13 @@ public class Operators { if(context == null){ return null; } - if(context instanceof CellRenderContext){ - if(WXEnvironment.isApkDebugable()){ - throw new IllegalArgumentException("rong context CellRenderContext, you should pass it's stack"); - } - context = ((CellRenderContext) context).stack; - } + // TODO +// if(context instanceof CellRenderContext){ +// if(WXEnvironment.isApkDebugable()){ +// throw new IllegalArgumentException("rong context CellRenderContext, you should pass it's stack"); +// } +// context = ((CellRenderContext) context).stack; +// } if(context instanceof ArrayStack){ ArrayStack stack = (ArrayStack) context; for(int index=stack.size()-1; index >= 0; index--){ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/el/parse/Parser.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Parser.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Parser.java index 76a6eed..4ee5a9d 100644 --- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Parser.java +++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Parser.java @@ -20,6 +20,7 @@ package com.taobao.weex.el.parse; import com.taobao.weex.WXEnvironment; import com.taobao.weex.utils.WXLogUtils; + import java.util.ArrayList; import java.util.List; @@ -62,7 +63,7 @@ public class Parser { /** * parse code to ast block. * */ - public static Token parse(String code){ + public static Token parse(String code){ try{ Parser parser = new Parser(code); return parser.parse(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/http/WXHttpUtil.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/http/WXHttpUtil.java b/android/sdk/src/main/java/com/taobao/weex/http/WXHttpUtil.java index 7bb4b03..4f58841 100644 --- a/android/sdk/src/main/java/com/taobao/weex/http/WXHttpUtil.java +++ b/android/sdk/src/main/java/com/taobao/weex/http/WXHttpUtil.java @@ -31,12 +31,12 @@ import java.util.Map; */ public class WXHttpUtil { - private static String sDefautUA = null; + private static String sDefaultUA = null; public static final String KEY_USER_AGENT = "user-agent"; public static String assembleUserAgent(Context ctx,Map<String, String> config) { - if (TextUtils.isEmpty(sDefautUA)) { + if (TextUtils.isEmpty(sDefaultUA)) { StringBuilder builder = new StringBuilder(); builder.append(config.get(WXConfig.sysModel)) .append("(Android/") @@ -60,8 +60,8 @@ public class WXHttpUtil { .append(TextUtils.isEmpty(config.get(WXConfig.externalUserAgent)) ? "" : " ") .append(WXViewUtils.getScreenWidth(ctx) + "x" + WXViewUtils.getScreenHeight(ctx)); - sDefautUA = builder.toString(); + sDefaultUA = builder.toString(); } - return sDefautUA; + return sDefaultUA; } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java b/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java index e3ac2f0..7028698 100644 --- a/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java +++ b/android/sdk/src/main/java/com/taobao/weex/http/WXStreamModule.java @@ -55,7 +55,7 @@ public class WXStreamModule extends WXModule { this(null); } public WXStreamModule(IWXHttpAdapter adapter){ - mAdapter = adapter; + mAdapter = adapter; } /** @@ -93,10 +93,10 @@ public class WXStreamModule extends WXModule { public void onResponse(WXResponse response, Map<String, String> headers) { if(callback != null && mWXSDKInstance != null) WXBridgeManager.getInstance().callback(mWXSDKInstance.getInstanceId(), callback, - (response == null || response.originalData == null) ? "{}" : - readAsString(response.originalData, - headers!=null?getHeader(headers,"Content-Type"):"" - )); + (response == null || response.originalData == null) ? "{}" : + readAsString(response.originalData, + headers!=null?getHeader(headers,"Content-Type"):"" + )); } }, null); } @@ -269,11 +269,11 @@ public class WXStreamModule extends WXModule { wxRequest.instanceId = mWXSDKInstance.getInstanceId(); if(options.getHeaders()!=null) - if (wxRequest.paramMap == null) { - wxRequest.paramMap = options.getHeaders(); - }else{ - wxRequest.paramMap.putAll(options.getHeaders()); - } + if (wxRequest.paramMap == null) { + wxRequest.paramMap = options.getHeaders(); + }else{ + wxRequest.paramMap.putAll(options.getHeaders()); + } IWXHttpAdapter adapter = ( mAdapter==null && mWXSDKInstance != null) ? mWXSDKInstance.getWXHttpAdapter() : mAdapter; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/layout/ContentBoxMeasurement.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/layout/ContentBoxMeasurement.java b/android/sdk/src/main/java/com/taobao/weex/layout/ContentBoxMeasurement.java new file mode 100644 index 0000000..d25a845 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/layout/ContentBoxMeasurement.java @@ -0,0 +1,78 @@ +/** + * 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.layout; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import com.taobao.weex.base.CalledByNative; +import com.taobao.weex.common.Destroyable; +import com.taobao.weex.ui.component.WXComponent; + +import java.io.Serializable; +import java.lang.ref.WeakReference; + +public abstract class ContentBoxMeasurement implements Serializable,Destroyable { + + @Nullable + protected WXComponent mComponent; + + protected float mMeasureWidth; + + protected float mMeasureHeight; + + public ContentBoxMeasurement() { + mComponent = null; + } + + public ContentBoxMeasurement(@NonNull WXComponent component) { + this.mComponent = component; + } + + /** uiThread = false **/ + @CalledByNative + public final void measure(float width, float height, int widthMeasureMode, int heightMeasureMode) { + measureInternal(width, height, widthMeasureMode, heightMeasureMode); + } + + /** uiThread = false **/ + public abstract void measureInternal(float width, float height, int widthMeasureMode, int heightMeasureMode); + + /** uiThread = false **/ + @CalledByNative + public abstract void layoutBefore(); + + /** uiThread = false **/ + @CalledByNative + public abstract void layoutAfter(float computedWidth, float computedHeight); + + @CalledByNative + public float getWidth() { + return mMeasureWidth; + } + + @CalledByNative + public float getHeight() { + return mMeasureHeight; + } + + @Override + public void destroy() { + mComponent = null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/layout/MeasureMode.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/layout/MeasureMode.java b/android/sdk/src/main/java/com/taobao/weex/layout/MeasureMode.java new file mode 100644 index 0000000..68670ba --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/layout/MeasureMode.java @@ -0,0 +1,40 @@ +/** + * 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.layout; + +import com.taobao.weex.base.CalledByNative; + +import java.io.Serializable; + +public class MeasureMode implements Serializable { + + public static int EXACTLY = 0; + + public static int UNSPECIFIED = 1; + + @CalledByNative + public static int getEXACTLY() { + return EXACTLY; + } + + @CalledByNative + public static int getUNSPECIFIED() { + return UNSPECIFIED; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/layout/MeasureSize.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/layout/MeasureSize.java b/android/sdk/src/main/java/com/taobao/weex/layout/MeasureSize.java new file mode 100644 index 0000000..ad671bf --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/layout/MeasureSize.java @@ -0,0 +1,42 @@ +/** + * 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.layout; + +import java.io.Serializable; + +public class MeasureSize implements Serializable{ + private float width; + private float height; + + public float getWidth() { + return width; + } + + public void setWidth(float width) { + this.width = width; + } + + public float getHeight() { + return height; + } + + public void setHeight(float height) { + this.height = height; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/layout/measurefunc/TextContentBoxMeasurement.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/layout/measurefunc/TextContentBoxMeasurement.java b/android/sdk/src/main/java/com/taobao/weex/layout/measurefunc/TextContentBoxMeasurement.java new file mode 100644 index 0000000..2a5ba3f --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/layout/measurefunc/TextContentBoxMeasurement.java @@ -0,0 +1,472 @@ +/** + * 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.layout.measurefunc; + +import android.graphics.Canvas; +import android.os.Build; +import android.os.Looper; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.text.Editable; +import android.text.Layout; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.SpannedString; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.AbsoluteSizeSpan; +import android.text.style.AlignmentSpan; +import android.text.style.ForegroundColorSpan; + +import com.taobao.weex.common.Constants; +import com.taobao.weex.dom.TextDecorationSpan; +import com.taobao.weex.dom.WXAttr; +import com.taobao.weex.dom.WXCustomStyleSpan; +import com.taobao.weex.dom.WXLineHeightSpan; +import com.taobao.weex.dom.WXStyle; +import com.taobao.weex.layout.ContentBoxMeasurement; +import com.taobao.weex.layout.MeasureMode; +import com.taobao.weex.layout.MeasureSize; +import com.taobao.weex.ui.component.WXComponent; +import com.taobao.weex.ui.component.WXText; +import com.taobao.weex.ui.component.WXTextDecoration; +import com.taobao.weex.utils.WXDomUtils; +import com.taobao.weex.utils.WXLogUtils; +import com.taobao.weex.utils.WXResourceUtils; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import static com.taobao.weex.dom.WXStyle.UNSET; +import static com.taobao.weex.utils.WXUtils.isUndefined; + +/** + * Created by miomin on 2018/3/9. + */ + +public class TextContentBoxMeasurement extends ContentBoxMeasurement { + + private static final Canvas DUMMY_CANVAS = new Canvas(); + + public TextContentBoxMeasurement(WXComponent component) { + super(component); + } + + class SetSpanOperation { + + protected final int start, end, flag; + protected final Object what; + + SetSpanOperation(int start, int end, Object what) { + this(start, end, what, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + } + + SetSpanOperation(int start, int end, Object what, int flag) { + this.start = start; + this.end = end; + this.what = what; + this.flag = flag; + } + + public void execute(Spannable sb) { + sb.setSpan(what, start, end, flag); + } + } + + private static final String ELLIPSIS = "\u2026"; + private boolean mIsColorSet = false; + private boolean hasBeenMeasured = false; + private int mColor; + private int mFontStyle = UNSET; + private int mFontWeight = UNSET; + private int mNumberOfLines = UNSET; + private int mFontSize = UNSET; + private int mLineHeight = UNSET; + private float previousWidth = Float.NaN; + private String mFontFamily = null; + private String mText = null; + private TextUtils.TruncateAt textOverflow; + private Layout.Alignment mAlignment; + private WXTextDecoration mTextDecoration = WXTextDecoration.NONE; + private TextPaint mTextPaint; + private @Nullable + Spanned spanned; + private @Nullable + Layout layout; + private AtomicReference<Layout> atomicReference = new AtomicReference<>(); + + /** + * uiThread = false + **/ + @Override + public void layoutBefore() { + mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + hasBeenMeasured = false; + updateStyleAndText(); + spanned = createSpanned(mText); + } + + /** + * uiThread = false + **/ + @Override + public void measureInternal(float width, float height, int widthMeasureMode, int heightMeasureMode) { + float measureWidth = width, measureHeight = height; + hasBeenMeasured = true; + float textWidth = getTextWidth(mTextPaint, width, widthMeasureMode == MeasureMode.EXACTLY); + + if (textWidth > 0 && mText != null) { + layout = createLayout(textWidth,null); + previousWidth = layout.getWidth(); + if (Float.isNaN(width)) { + measureWidth = layout.getWidth(); + } else { + measureWidth = Math.min(layout.getWidth(), measureWidth); + } + + if (Float.isNaN(height)) { + measureHeight = layout.getHeight(); + } + } else { + if (widthMeasureMode == MeasureMode.UNSPECIFIED) { + measureWidth = 0; + } + if (heightMeasureMode == MeasureMode.UNSPECIFIED) { + measureHeight = 0; + } + } + mMeasureWidth = measureWidth; + mMeasureHeight = measureHeight; + } + + /** + * uiThread = false + **/ + @Override + public void layoutAfter(float computedWidth, float computedHeight) { + if (hasBeenMeasured) { + if (layout != null && + WXDomUtils.getContentWidth(mComponent.getPadding(), mComponent.getBorder(), computedWidth) + != previousWidth) { + recalculateLayout(computedWidth); + } + } else { + updateStyleAndText(); + recalculateLayout(computedWidth); + } + hasBeenMeasured = false; + if (layout != null && !layout.equals(atomicReference.get()) && + Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if (Thread.currentThread() != Looper.getMainLooper().getThread()) { + warmUpTextLayoutCache(layout); + } + } + swap(); + mComponent.getInstance().runOnUiThread(new Runnable() { + @Override + public void run() { + mComponent.updateExtra(atomicReference.get()); + } + }); + } + + private void updateStyleAndText() { + updateStyleImp(mComponent.getStyles()); + mText = WXAttr.getValue(mComponent.getAttrs()); + } + + /** + * Record the property according to the given style + * + * @param style the give style. + */ + private void updateStyleImp(Map<String, Object> style) { + if (style != null) { + if (style.containsKey(Constants.Name.LINES)) { + int lines = WXStyle.getLines(style); + mNumberOfLines = lines > 0 ? lines : UNSET; + } + if (style.containsKey(Constants.Name.FONT_SIZE)) { + mFontSize = WXStyle.getFontSize(style, mComponent.getViewPortWidth()); + } + if (style.containsKey(Constants.Name.FONT_WEIGHT)) { + mFontWeight = WXStyle.getFontWeight(style); + } + if (style.containsKey(Constants.Name.FONT_STYLE)) { + mFontStyle = WXStyle.getFontStyle(style); + } + if (style.containsKey(Constants.Name.COLOR)) { + mColor = WXResourceUtils.getColor(WXStyle.getTextColor(style)); + mIsColorSet = mColor != Integer.MIN_VALUE; + } + if (style.containsKey(Constants.Name.TEXT_DECORATION)) { + mTextDecoration = WXStyle.getTextDecoration(style); + } + if (style.containsKey(Constants.Name.FONT_FAMILY)) { + mFontFamily = WXStyle.getFontFamily(style); + } + mAlignment = WXStyle.getTextAlignment(style); + textOverflow = WXStyle.getTextOverflow(style); + int lineHeight = WXStyle.getLineHeight(style, mComponent.getViewPortWidth()); + if (lineHeight != UNSET) { + mLineHeight = lineHeight; + } + } + } + + /** + * Update {@link #spanned} according to the give charSequence and styles + * + * @param text the give raw text. + * @return an Spanned contains text and spans + */ + protected + @NonNull + Spanned createSpanned(String text) { + if (!TextUtils.isEmpty(text)) { + SpannableString spannable = new SpannableString(text); + updateSpannable(spannable, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + return spannable; + } + return new SpannableString(""); + } + + protected void updateSpannable(Spannable spannable, int spanFlag) { + int end = spannable.length(); + if (mFontSize == UNSET) { + setSpan(spannable, new AbsoluteSizeSpan(WXText.sDEFAULT_SIZE), 0, end, spanFlag); + } + else{ + setSpan(spannable, new AbsoluteSizeSpan(mFontSize), 0, end, spanFlag); + } + + if (mLineHeight != UNSET) { + setSpan(spannable, new WXLineHeightSpan(mLineHeight), 0, end, spanFlag); + } + + setSpan(spannable, new AlignmentSpan.Standard(mAlignment), 0, end, spanFlag); + + if (mFontStyle != UNSET || mFontWeight != UNSET || mFontFamily != null) { + setSpan(spannable, new WXCustomStyleSpan(mFontStyle, mFontWeight, mFontFamily), 0, end, spanFlag); + } + + if (mIsColorSet) { + setSpan(spannable, new ForegroundColorSpan(mColor), 0, end, spanFlag); + } + + if (mTextDecoration == WXTextDecoration.UNDERLINE || mTextDecoration == WXTextDecoration.LINETHROUGH) { + setSpan(spannable, new TextDecorationSpan(mTextDecoration), 0, end, spanFlag); + } + } + + private void setSpan(Spannable spannable, Object what, int start, int end, int spanFlag){ + spannable.setSpan(what, start, end, spanFlag); + } + + /** + * Get text width according to constrain of outerWidth with and forceToDesired + * + * @param textPaint paint used to measure text + * @param outerWidth the width that css-layout desired. + * @param forceToDesired if set true, the return value will be outerWidth, no matter what the width + * of text is. + * @return if forceToDesired is false, it will be the minimum value of the width of text and + * outerWidth in case of outerWidth is defined, in other case, it will be outer width. + */ + private float getTextWidth(TextPaint textPaint, float outerWidth, boolean forceToDesired) { + if (mText == null) { + if (forceToDesired) { + return outerWidth; + } + return 0; + } + else { + float textWidth; + if (forceToDesired) { + textWidth = outerWidth; + } else { + float desiredWidth = Layout.getDesiredWidth(spanned, textPaint); + if (isUndefined(outerWidth) || desiredWidth < outerWidth) { + textWidth = desiredWidth; + } else { + textWidth = outerWidth; + } + } + return textWidth; + } + } + + /** + * Update layout according to {@link #mText} and span + * + * @param width the specified width. + * @param forceWidth If true, force the text width to the specified width, otherwise, text width + * may equals to or be smaller than the specified width. + * @param previousLayout the result of previous layout, could be null. + */ + private + @NonNull + Layout createLayout(final float textWidth, @Nullable Layout previousLayout) { + Layout layout; + if (previousWidth != textWidth || previousLayout == null) { + layout = new StaticLayout(spanned, mTextPaint, (int) Math.ceil(textWidth), + Layout.Alignment.ALIGN_NORMAL, 1, 0, false); + } else { + layout = previousLayout; + } + if (mNumberOfLines != UNSET && mNumberOfLines > 0 && mNumberOfLines < layout.getLineCount()) { + int lastLineStart, lastLineEnd; + lastLineStart = layout.getLineStart(mNumberOfLines - 1); + lastLineEnd = layout.getLineEnd(mNumberOfLines - 1); + if (lastLineStart < lastLineEnd) { + SpannableStringBuilder builder = null; + if (lastLineStart > 0) { + builder = new SpannableStringBuilder(spanned.subSequence(0, lastLineStart)); + } else { + builder = new SpannableStringBuilder(); + } + Editable lastLine = new SpannableStringBuilder(spanned.subSequence(lastLineStart, lastLineEnd)); + builder.append(truncate(lastLine, mTextPaint, (int) Math.ceil(textWidth), textOverflow)); + adjustSpansRange(spanned, builder); + spanned = builder; + return new StaticLayout(spanned, mTextPaint, (int) Math.ceil(textWidth), + Layout.Alignment.ALIGN_NORMAL, 1, 0, false); + } + } + return layout; + } + + /** + * Truncate the source span to the specified lines. + * Caller of this method must ensure that the lines of text is <strong>greater than desired lines and need truncate</strong>. + * Otherwise, unexpected behavior may happen. + * + * @param source The source span. + * @param paint the textPaint + * @param desired specified lines. + * @param truncateAt truncate method, null value means clipping overflow text directly, non-null value means using ellipsis strategy to clip + * @return The spans after clipped. + */ + private + @NonNull + Spanned truncate(@Nullable Editable source, @NonNull TextPaint paint, + int desired, @Nullable TextUtils.TruncateAt truncateAt) { + Spanned ret = new SpannedString(""); + if (!TextUtils.isEmpty(source) && source.length() > 0) { + if (truncateAt != null) { + source.append(ELLIPSIS); + Object[] spans = source.getSpans(0, source.length(), Object.class); + for (Object span : spans) { + int start = source.getSpanStart(span); + int end = source.getSpanEnd(span); + if (start == 0 && end == source.length() - 1) { + source.removeSpan(span); + source.setSpan(span, 0, source.length(), source.getSpanFlags(span)); + } + } + } + + StaticLayout layout; + int startOffset; + + while (source.length() > 1) { + startOffset = source.length() - 1; + if (truncateAt != null) { + startOffset -= 1; + } + source.delete(startOffset, startOffset + 1); + layout = new StaticLayout(source, paint, desired, Layout.Alignment.ALIGN_NORMAL, 1, 0, false); + if (layout.getLineCount() <= 1) { + ret = source; + break; + } + } + } + return ret; + } + + /** + * Adjust span range after truncate due to the wrong span range during span copy and slicing. + * + * @param beforeTruncate The span before truncate + * @param afterTruncate The span after truncate + */ + private void adjustSpansRange(@NonNull Spanned beforeTruncate, @NonNull Spannable afterTruncate) { + Object[] spans = beforeTruncate.getSpans(0, beforeTruncate.length(), Object.class); + for (Object span : spans) { + int start = beforeTruncate.getSpanStart(span); + int end = beforeTruncate.getSpanEnd(span); + if (start == 0 && end == beforeTruncate.length()) { + afterTruncate.removeSpan(span); + afterTruncate.setSpan(span, 0, afterTruncate.length(), beforeTruncate.getSpanFlags(span)); + } + } + } + + private void recalculateLayout(float computedWidth) { + float contentWidth = WXDomUtils.getContentWidth(mComponent.getPadding(), mComponent.getBorder(), computedWidth); + if (contentWidth > 0) { + spanned = createSpanned(mText); + if (mText != null) { + layout = createLayout(contentWidth, layout); + previousWidth = layout.getWidth(); + } else { + previousWidth = 0; + } + } + } + + /** + * As warming up TextLayoutCache done in the DOM thread may manipulate UI operation, + * there may be some exception, in which case the exception is ignored. After all, + * this is just a warm up operation. + * + * @return false for warm up failure, otherwise returns true. + */ + private boolean warmUpTextLayoutCache(Layout layout) { + boolean result; + try { + layout.draw(DUMMY_CANVAS); + result = true; + } catch (Exception e) { + WXLogUtils.eTag("TextWarmUp", e); + result = false; + } + return result; + } + + /** + * Move the reference of current layout to the {@link AtomicReference} for further use, + * then clear current layout. + */ + private void swap() { + if (layout != null) { + atomicReference.set(layout); + layout = null; + } + hasBeenMeasured = false; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/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 index 129dcec..27c75f8 100644 --- a/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java +++ b/android/sdk/src/main/java/com/taobao/weex/performance/WXAnalyzerDataTransfer.java @@ -67,11 +67,11 @@ public class WXAnalyzerDataTransfer { } data = new JSONObject() - .put("instanceId", instanceId) - .put("url", instance.getBundleUrl()) - .put("dimensionMap", dimensionMap) - .put("measureMap", measureMap) - .toString(); + .put("instanceId", instanceId) + .put("url", instance.getBundleUrl()) + .put("dimensionMap", dimensionMap) + .put("measureMap", measureMap) + .toString(); } catch (Exception e) { e.printStackTrace(); @@ -98,12 +98,12 @@ public class WXAnalyzerDataTransfer { 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(); + .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(); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java b/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java index da1fc4f..0dc11ce 100644 --- a/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java +++ b/android/sdk/src/main/java/com/taobao/weex/tracing/WXTracing.java @@ -39,7 +39,7 @@ public class WXTracing { public static int nextId() { return sIdGenerator.getAndIncrement(); } - + public static boolean isAvailable() { return WXEnvironment.isApkDebugable(); } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/ComponentCreator.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/ComponentCreator.java b/android/sdk/src/main/java/com/taobao/weex/ui/ComponentCreator.java index eee2b42..c2e7f15 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/ComponentCreator.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/ComponentCreator.java @@ -19,7 +19,7 @@ package com.taobao.weex.ui; import com.taobao.weex.WXSDKInstance; -import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.ui.action.BasicComponentData; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.ui.component.WXVContainer; @@ -29,5 +29,5 @@ import java.lang.reflect.InvocationTargetException; * Created by sospartan on 7/27/16. */ public interface ComponentCreator { - WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException; + WXComponent createInstance(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) throws IllegalAccessException, InvocationTargetException, InstantiationException; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/ExternalLoaderComponentHolder.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/ExternalLoaderComponentHolder.java b/android/sdk/src/main/java/com/taobao/weex/ui/ExternalLoaderComponentHolder.java index fb487dc..312a538 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/ExternalLoaderComponentHolder.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/ExternalLoaderComponentHolder.java @@ -22,7 +22,7 @@ import android.util.Pair; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.bridge.Invoker; -import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.ui.action.BasicComponentData; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.ui.component.WXVContainer; @@ -42,7 +42,7 @@ public class ExternalLoaderComponentHolder implements IFComponentHolder { private Class mClass; - public ExternalLoaderComponentHolder(String type, IExternalComponentGetter clzGetter) { + public ExternalLoaderComponentHolder(String type,IExternalComponentGetter clzGetter) { this.mClzGetter = clzGetter; mType = type; } @@ -62,15 +62,13 @@ public class ExternalLoaderComponentHolder implements IFComponentHolder { return true; } - - @Override - public synchronized WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { - if(mClass == null){ - mClass = mClzGetter.getExternalComponentClass(mType,instance); + public synchronized WXComponent createInstance(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) throws IllegalAccessException, InvocationTargetException, InstantiationException { + if (mClass == null) { + mClass = mClzGetter.getExternalComponentClass(mType, instance); } ComponentCreator creator = new SimpleComponentHolder.ClazzComponentCreator(mClass); - WXComponent component = creator.createInstance(instance,node,parent); + WXComponent component = creator.createInstance(instance, parent, basicComponentData); component.bindHolder(this); return component; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/IWXRenderTask.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/IWXRenderTask.java b/android/sdk/src/main/java/com/taobao/weex/ui/IWXRenderTask.java deleted file mode 100644 index efe0d3e..0000000 --- a/android/sdk/src/main/java/com/taobao/weex/ui/IWXRenderTask.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.ui; - -import com.taobao.weex.common.IWXTask; - -public interface IWXRenderTask extends IWXTask { - - void execute(); -} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/RenderActionContextImpl.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/RenderActionContextImpl.java b/android/sdk/src/main/java/com/taobao/weex/ui/RenderActionContextImpl.java deleted file mode 100644 index e439022..0000000 --- a/android/sdk/src/main/java/com/taobao/weex/ui/RenderActionContextImpl.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.ui; - -import android.graphics.Rect; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.alibaba.fastjson.JSONObject; -import com.taobao.weex.WXSDKInstance; -import com.taobao.weex.bridge.JSCallback; -import com.taobao.weex.common.WXRenderStrategy; -import com.taobao.weex.dom.WXDomObject; -import com.taobao.weex.dom.flex.Spacing; -import com.taobao.weex.dom.RenderActionContext; -import com.taobao.weex.ui.animation.WXAnimationBean; -import com.taobao.weex.ui.animation.WXAnimationModule; -import com.taobao.weex.ui.component.Scrollable; -import com.taobao.weex.ui.component.WXComponent; -import com.taobao.weex.ui.component.WXComponentFactory; -import com.taobao.weex.ui.component.WXVContainer; -import com.taobao.weex.utils.WXViewUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * Class for rendering view. Method in this class should be run in main thread. - * This class is also <strong>not</storng> thread safe. - * This class is very similar to {@link com.taobao.weex.dom.WXDomStatement} - * @see com.taobao.weex.dom.WXDomStatement - */ -class RenderActionContextImpl implements RenderActionContext { - - private Map<String, WXComponent> mRegistry; - private WXSDKInstance mWXSDKInstance; - /** - * The container for weex root view. - */ - - public RenderActionContextImpl(WXSDKInstance instance) { - mWXSDKInstance = instance; - mRegistry = new HashMap<>(); - } - - /** - * @see com.taobao.weex.dom.WXDomStatement#destroy() - */ - public void destroy() { - mWXSDKInstance = null; - mRegistry.clear(); - } - - public WXSDKInstance getWXSDKInstance() { - return mWXSDKInstance; - } - - /** - * set layout information of View - */ - void setLayout(String ref, WXDomObject domObject) { - WXComponent component = mRegistry.get(ref); - if (component == null) { - return; - } - component.setLayout(domObject); - } - - /** - * set extra information of View - */ - void setExtra(String ref, Object extra) { - WXComponent component = mRegistry.get(ref); - if (component == null) { - return; - } - component.updateExtra(extra); - } - - @Override - public WXSDKInstance getInstance() { - return mWXSDKInstance; - } - - @Override - public WXComponent getComponent(String ref) { - return mRegistry.get(ref); - } - - public void registerComponent(String ref, WXComponent comp) { - mRegistry.put(ref,comp); - } - - public WXComponent unregisterComponent(String ref) { - return mRegistry.remove(ref); - } -} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/RenderContextImpl.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/RenderContextImpl.java b/android/sdk/src/main/java/com/taobao/weex/ui/RenderContextImpl.java new file mode 100644 index 0000000..c63bc2b --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/RenderContextImpl.java @@ -0,0 +1,75 @@ +/* + * 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.ui; + +import android.support.v4.util.ArrayMap; +import android.util.Log; + +import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.dom.RenderContext; +import com.taobao.weex.ui.component.WXComponent; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Class for rendering view. Method in this class should be run in main thread. + * This class is also <strong>not</storng> thread safe. + */ +class RenderContextImpl implements RenderContext { + + private Map<String, WXComponent> mRegistry; + private WXSDKInstance mWXSDKInstance; + + public RenderContextImpl(WXSDKInstance instance) { + mWXSDKInstance = instance; + mRegistry = new ArrayMap<>(); + } + + public void destroy() { + mWXSDKInstance = null; + mRegistry.clear(); + } + + public WXSDKInstance getWXSDKInstance() { + return mWXSDKInstance; + } + + @Override + public WXSDKInstance getInstance() { + return mWXSDKInstance; + } + + @Override + public WXComponent getComponent(String ref) { + return mRegistry.get(ref); + } + + public void registerComponent(String ref, WXComponent comp) { + mRegistry.put(ref, comp); + } + + public WXComponent unregisterComponent(String ref) { + return mRegistry.remove(ref); + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/SimpleComponentHolder.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/SimpleComponentHolder.java b/android/sdk/src/main/java/com/taobao/weex/ui/SimpleComponentHolder.java index cfbe2be..9743582 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/SimpleComponentHolder.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/SimpleComponentHolder.java @@ -27,7 +27,7 @@ import com.taobao.weex.bridge.Invoker; import com.taobao.weex.bridge.MethodInvoker; import com.taobao.weex.annotation.Component; import com.taobao.weex.common.WXRuntimeException; -import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.ui.action.BasicComponentData; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.ui.component.WXComponentProp; import com.taobao.weex.ui.component.WXVContainer; @@ -60,20 +60,20 @@ public class SimpleComponentHolder implements IFComponentHolder{ mCompClz = c; } - private void loadConstructor(){ + private void loadConstructor() { Class<? extends WXComponent> c = mCompClz; Constructor<? extends WXComponent> constructor; try { - constructor = c.getConstructor(WXSDKInstance.class, WXDomObject.class, WXVContainer.class); + constructor = c.getConstructor(WXSDKInstance.class, WXVContainer.class, BasicComponentData.class); } catch (NoSuchMethodException e) { - WXLogUtils.d("ClazzComponentCreator","Use deprecated component constructor"); + WXLogUtils.d("ClazzComponentCreator", "Use deprecated component constructor"); try { //compatible deprecated constructor with 4 args - constructor = c.getConstructor(WXSDKInstance.class, WXDomObject.class, WXVContainer.class, boolean.class); + constructor = c.getConstructor(WXSDKInstance.class, WXVContainer.class, boolean.class, BasicComponentData.class); } catch (NoSuchMethodException e1) { try { //compatible deprecated constructor with 5 args - constructor = c.getConstructor(WXSDKInstance.class, WXDomObject.class, WXVContainer.class,String.class, boolean.class); + constructor = c.getConstructor(WXSDKInstance.class, WXVContainer.class, String.class, boolean.class, BasicComponentData.class); } catch (NoSuchMethodException e2) { throw new WXRuntimeException("Can't find constructor of component."); } @@ -83,7 +83,7 @@ public class SimpleComponentHolder implements IFComponentHolder{ } @Override - public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { + public WXComponent createInstance(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) throws IllegalAccessException, InvocationTargetException, InstantiationException { if(mConstructor == null){ loadConstructor(); } @@ -91,12 +91,12 @@ public class SimpleComponentHolder implements IFComponentHolder{ WXComponent component; if(parameters == 3){ - component = mConstructor.newInstance(instance,node,parent); + component = mConstructor.newInstance(instance,parent, basicComponentData); }else if(parameters == 4){ - component = mConstructor.newInstance(instance,node,parent,false); + component = mConstructor.newInstance(instance,parent,false, basicComponentData); }else{ //compatible deprecated constructor - component = mConstructor.newInstance(instance,node,parent,instance.getInstanceId(),parent.isLazy()); + component = mConstructor.newInstance(instance,parent,instance.getInstanceId(),parent.isLazy()); } return component; } @@ -181,8 +181,8 @@ public class SimpleComponentHolder implements IFComponentHolder{ @Override - public synchronized WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { - WXComponent component = mCreator.createInstance(instance,node,parent); + public synchronized WXComponent createInstance(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) throws IllegalAccessException, InvocationTargetException, InstantiationException { + WXComponent component = mCreator.createInstance(instance, parent, basicComponentData); component.bindHolder(this); return component; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/WXComponentRegistry.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/WXComponentRegistry.java b/android/sdk/src/main/java/com/taobao/weex/ui/WXComponentRegistry.java index 39e3b89..9d8165f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/WXComponentRegistry.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/WXComponentRegistry.java @@ -19,6 +19,7 @@ package com.taobao.weex.ui; import android.text.TextUtils; +import android.util.Log; import com.taobao.weex.WXSDKManager; import com.taobao.weex.bridge.WXBridgeManager; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderHandler.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderHandler.java b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderHandler.java index e133d7b..99cba05 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderHandler.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderHandler.java @@ -6,9 +6,9 @@ * 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 @@ -24,12 +24,18 @@ import android.os.Message; class WXRenderHandler extends Handler { - public WXRenderHandler() { - super(Looper.getMainLooper()); - } + public WXRenderHandler() { + super(Looper.getMainLooper()); + } - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - } + public final boolean post(String instanceId, Runnable r) { + Message msg = Message.obtain(this, r); + msg.obj = instanceId.hashCode(); + return sendMessageDelayed(msg, 0); + } + + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java index edcc560..04d9395 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/WXRenderManager.java @@ -18,20 +18,18 @@ */ package com.taobao.weex.ui; -import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; import android.text.TextUtils; import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.WXSDKManager; import com.taobao.weex.common.WXRuntimeException; import com.taobao.weex.common.WXThread; -import com.taobao.weex.dom.RenderAction; -import com.taobao.weex.dom.RenderActionContext; -import com.taobao.weex.dom.WXDomObject; -import com.taobao.weex.dom.action.AbstractAddElementAction; -import com.taobao.weex.dom.action.TraceableAction; -import com.taobao.weex.tracing.Stopwatch; -import com.taobao.weex.tracing.WXTracing; +import com.taobao.weex.dom.RenderContext; +import com.taobao.weex.ui.action.BasicGraphicAction; +import com.taobao.weex.ui.action.IExecutable; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.utils.WXUtils; @@ -41,33 +39,34 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** - * Manager class for render operation, mainly for managing {@link RenderActionContextImpl}. + * Manager class for render operation, mainly for managing {@link RenderContextImpl}. * This is <strong>not</strong> a thread-safe class */ public class WXRenderManager { - private ConcurrentHashMap<String, RenderActionContextImpl> mRegistries; + private ConcurrentHashMap<String, RenderContextImpl> mRenderContext; private WXRenderHandler mWXRenderHandler; public WXRenderManager() { - mRegistries = new ConcurrentHashMap<>(); + mRenderContext = new ConcurrentHashMap<>(); mWXRenderHandler = new WXRenderHandler(); } - public RenderActionContext getRenderContext(String instanceId) { - return mRegistries.get(instanceId); + public RenderContext getRenderContext(String instanceId) { + return mRenderContext.get(instanceId); } - public @Nullable WXComponent getWXComponent(String instanceId, String ref) { - if(instanceId == null || TextUtils.isEmpty(ref)){ + public @Nullable + WXComponent getWXComponent(String instanceId, String ref) { + if (instanceId == null || TextUtils.isEmpty(ref)) { return null; } - RenderActionContext stmt = getRenderContext(instanceId); - return stmt == null?null:stmt.getComponent(ref); + RenderContext stmt = getRenderContext(instanceId); + return stmt == null ? null : stmt.getComponent(ref); } public WXSDKInstance getWXSDKInstance(String instanceId) { - RenderActionContextImpl statement = mRegistries.get(instanceId); + RenderContextImpl statement = mRenderContext.get(instanceId); if (statement == null) { return null; } @@ -78,95 +77,52 @@ public class WXRenderManager { mWXRenderHandler.postDelayed(WXThread.secure(runnable), delayMillis); } + @RestrictTo(Scope.LIBRARY) + public void postOnUiThread(Runnable runnable){ + mWXRenderHandler.post(WXThread.secure(runnable)); + } + + @RestrictTo(Scope.LIBRARY) + public void removeTask(Runnable runnable){ + mWXRenderHandler.removeCallbacks(runnable); + } + /** * Remove renderStatement, can only be invoked in UI thread. + * * @param instanceId {@link WXSDKInstance#mInstanceId} */ public void removeRenderStatement(String instanceId) { if (!WXUtils.isUiThread()) { throw new WXRuntimeException("[WXRenderManager] removeRenderStatement can only be called in main thread"); } - RenderActionContextImpl statement = mRegistries.remove(instanceId); + RenderContextImpl statement = mRenderContext.remove(instanceId); + if (statement != null) { statement.destroy(); } + final Object token = instanceId == null ? null : instanceId.hashCode(); + mWXRenderHandler.removeCallbacksAndMessages(token); } - //TODO Use runnable temporarily - public void runOnThread(final String instanceId, final IWXRenderTask task) { - mWXRenderHandler.post(WXThread.secure(new Runnable() { - - @Override - public void run() { - if (mRegistries.get(instanceId) == null) { - return; - } - task.execute(); - } - })); - } - - public void runOnThread(final String instanceId, final RenderAction action) { - final long start = SystemClock.uptimeMillis(); - mWXRenderHandler.post(WXThread.secure(new Runnable() { - @Override - public void run() { - if (mRegistries.get(instanceId) == null) { - return; - } - if (WXTracing.isAvailable() && action instanceof TraceableAction) { - ((TraceableAction) action).mUIQueueTime = SystemClock.uptimeMillis() - start; - } - - long start = System.currentTimeMillis(); - long uiNanos = System.nanoTime(); - action.executeRender(getRenderContext(instanceId)); - - if (WXTracing.isAvailable()) { - uiNanos = System.nanoTime() - uiNanos; - if (action instanceof TraceableAction) { - if (!(action instanceof AbstractAddElementAction)) { - WXTracing.TraceEvent uiExecuteEvent = WXTracing.newEvent("UIExecute", instanceId, ((TraceableAction) action).mTracingEventId); - uiExecuteEvent.duration = Stopwatch.nanosToMillis(uiNanos); - uiExecuteEvent.ts = start; - uiExecuteEvent.submit(); - } - ((TraceableAction) action).onFinishUIExecute(); - } - } - } - })); - } - - public void registerInstance(WXSDKInstance instance) { - mRegistries.put(instance.getInstanceId(), new RenderActionContextImpl(instance)); - } - - public void setLayout(String instanceId, String ref, WXDomObject domObject) { - RenderActionContextImpl statement = mRegistries.get(instanceId); - if (statement == null) { + public void postGraphicAction(final String instanceId, final BasicGraphicAction action) { + final RenderContextImpl renderContext = mRenderContext.get(instanceId); + if (renderContext == null) { return; } - statement.setLayout(ref, domObject); + mWXRenderHandler.post(instanceId, action); } - /** - * Set extra info, other than attribute and style - */ - public void setExtra(String instanceId, String ref, Object extra) { - RenderActionContextImpl statement = mRegistries.get(instanceId); - if (statement == null) { - return; - } - statement.setExtra(ref, extra); + public void registerInstance(WXSDKInstance instance) { + mRenderContext.put(instance.getInstanceId(), new RenderContextImpl(instance)); } public List<WXSDKInstance> getAllInstances() { ArrayList<WXSDKInstance> instances = null; - if (mRegistries != null && !mRegistries.isEmpty()) { + if (mRenderContext != null && !mRenderContext.isEmpty()) { instances = new ArrayList<WXSDKInstance>(); - for (Map.Entry<String, RenderActionContextImpl> entry : mRegistries.entrySet()) { - RenderActionContextImpl renderStatement = entry.getValue(); + for (Map.Entry<String, RenderContextImpl> entry : mRenderContext.entrySet()) { + RenderContextImpl renderStatement = entry.getValue(); if (renderStatement != null) { instances.add(renderStatement.getWXSDKInstance()); } @@ -176,10 +132,18 @@ public class WXRenderManager { } public void registerComponent(String instanceId, String ref, WXComponent comp) { - RenderActionContextImpl statement = mRegistries.get(instanceId); + RenderContextImpl statement = mRenderContext.get(instanceId); if (statement != null) { - statement.registerComponent(ref,comp); + statement.registerComponent(ref, comp); } } + public WXComponent unregisterComponent(String instanceId, String ref) { + RenderContextImpl statement = mRenderContext.get(instanceId); + if (statement != null) { + return statement.unregisterComponent(ref); + } else { + return null; + } + } }
