From commits-return-10972-archive-asf-public=cust-asf.ponee.io@weex.incubator.apache.org Thu Jan 18 10:31:19 2018 Return-Path: X-Original-To: archive-asf-public@eu.ponee.io Delivered-To: archive-asf-public@eu.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by mx-eu-01.ponee.io (Postfix) with ESMTP id 7A932180654 for ; Thu, 18 Jan 2018 10:31:19 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 6A20C160C36; Thu, 18 Jan 2018 09:31:19 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 3A5E3160C2B for ; Thu, 18 Jan 2018 10:31:18 +0100 (CET) Received: (qmail 696 invoked by uid 500); 18 Jan 2018 09:31:17 -0000 Mailing-List: contact commits-help@weex.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@weex.incubator.apache.org Delivered-To: mailing list commits@weex.incubator.apache.org Received: (qmail 686 invoked by uid 99); 18 Jan 2018 09:31:17 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jan 2018 09:31:17 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id D40A51A6E37 for ; Thu, 18 Jan 2018 09:31:16 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.23 X-Spam-Level: X-Spam-Status: No, score=-4.23 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id E_i4ve4imaCh for ; Thu, 18 Jan 2018 09:31:13 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with SMTP id E1A425F27E for ; Thu, 18 Jan 2018 09:31:12 +0000 (UTC) Received: (qmail 663 invoked by uid 99); 18 Jan 2018 09:31:12 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jan 2018 09:31:12 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 5D1AEDFD7B; Thu, 18 Jan 2018 09:31:12 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: acton393@apache.org To: commits@weex.incubator.apache.org Message-Id: <722890608fa247779e0cc70121ff2ef8@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: incubator-weex git commit: [android][WEEX-185] Embed Support Auto Memory Manage Date: Thu, 18 Jan 2018 09:31:12 +0000 (UTC) Repository: incubator-weex Updated Branches: refs/heads/master a2f1f13a9 -> b582c193b [android][WEEX-185] Embed Support Auto Memory Manage Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/b582c193 Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/b582c193 Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/b582c193 Branch: refs/heads/master Commit: b582c193b62654568b58eb688fae337d0c6d0f9f Parents: a2f1f13 Author: jianbai.gbj Authored: Wed Jan 3 17:22:53 2018 +0800 Committer: acton393 Committed: Thu Jan 18 17:30:26 2018 +0800 ---------------------------------------------------------------------- .../java/com/taobao/weex/WXSDKInstance.java | 14 ++ .../java/com/taobao/weex/common/Constants.java | 4 + .../com/taobao/weex/ui/component/WXEmbed.java | 152 +++++++++++++++++-- .../taobao/weex/ui/component/WXVContainer.java | 75 +++++++++ .../com/taobao/weex/ui/view/WXImageView.java | 6 +- .../weex/ui/component/PriorityQueueTest.java | 56 +++++++ 6 files changed, 289 insertions(+), 18 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b582c193/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java index 2c1b47b..9e452b5 100644 --- a/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java +++ b/android/sdk/src/main/java/com/taobao/weex/WXSDKInstance.java @@ -71,6 +71,7 @@ import com.taobao.weex.ui.component.NestedContainer; import com.taobao.weex.ui.component.WXBasicComponentType; import com.taobao.weex.ui.component.WXComponent; import com.taobao.weex.ui.component.WXComponentFactory; +import com.taobao.weex.ui.component.WXEmbed; import com.taobao.weex.ui.flat.FlatGUIContext; import com.taobao.weex.ui.view.WXScrollView; import com.taobao.weex.ui.view.WXScrollView.WXScrollViewListener; @@ -89,6 +90,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.PriorityQueue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -173,6 +175,11 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. private ComponentObserver mComponentObserver; private boolean mIsCommitedDomAtionExp = false; + public PriorityQueue hiddenEmbeds; + + private int maxHiddenEmbedsNum = -1; //max hidden embed num, -1 standard for ulimit + + public boolean getismIsCommitedDomAtionExp() { return mIsCommitedDomAtionExp; } @@ -181,6 +188,13 @@ public class WXSDKInstance implements IWXActivityStateListener,DomContext, View. this.mIsCommitedDomAtionExp = mIsCommitedDomAtionExp; } + public int getMaxHiddenEmbedsNum() { + return maxHiddenEmbedsNum; + } + + public void setMaxHiddenEmbedsNum(int maxHiddenEmbedsNum) { + this.maxHiddenEmbedsNum = maxHiddenEmbedsNum; + } /** * If anchor is created manually(etc. define a layout xml resource ), http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b582c193/android/sdk/src/main/java/com/taobao/weex/common/Constants.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java index 3bb91f6..66c4df0 100644 --- a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java +++ b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java @@ -195,6 +195,10 @@ public class Constants { String OVERFLOW_HIDDEN_HEIGHT = "overflowHiddenHeight"; String OVERFLOW_HIDDEN_WIDTH = "overflowHiddenWidth"; + String PRIORITY = "priority"; + + String STRATEGY = "strategy"; + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b582c193/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java index 9b95be3..6002a5d 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXEmbed.java @@ -29,6 +29,7 @@ import android.widget.ImageView; import com.taobao.weappplus_sdk.R; import com.taobao.weex.IWXRenderListener; +import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXRenderErrorCode; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.annotation.Component; @@ -39,8 +40,22 @@ import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.utils.WXLogUtils; import com.taobao.weex.utils.WXUtils; import com.taobao.weex.utils.WXViewUtils; + +import java.util.Comparator; +import java.util.PriorityQueue; + @Component(lazyload = false) -public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleListener,NestedContainer { +public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleListener,NestedContainer{ + + + public static final String STRATEGY_NONE = "none"; + public static final String STRATEGY_NORMAL = "normal"; + public static final String STRATEGY_HIGH = "high"; + + + public static final String PRIORITY_LOW = "low"; + public static final String PRIORITY_NORMAL = "normal"; + public static final String PRIORITY_HIGH = "high"; public static final String ITEM_ID = "itemId"; @@ -52,6 +67,13 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis private boolean mIsVisible = true; private EmbedRenderListener mListener; + + private String priority = PRIORITY_NORMAL; + + private String strategy = "normal"; //none, normal, high(ignore priority) + + private long hiddenTime; + public interface EmbedManager { WXEmbed getEmbed(String itemId); void putEmbed(String itemId,WXEmbed comp); @@ -182,6 +204,8 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis ((EmbedManager) instance).putEmbed(itemId.toString(), this); } } + this.priority = WXUtils.getString(node.getAttrs().get(Constants.Name.PRIORITY), PRIORITY_NORMAL); + this.strategy = WXUtils.getString(node.getAttrs().get(Constants.Name.STRATEGY), STRATEGY_NONE); } @Override @@ -202,6 +226,12 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis if (src != null) setSrc(src); return true; + case Constants.Name.PRIORITY: + String priority = WXUtils.getString(param,null); + if (priority != null){ + setPriority(priority); + } + return true; } return super.setProperty(key, param); } @@ -245,6 +275,15 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis return src; } + + @WXComponentProp(name = Constants.Name.PRIORITY) + public void setPriority(String priority) { + if(TextUtils.isEmpty(priority)){ + return; + } + this.priority = priority; + } + /** * Load embed content, default behavior is create a nested instance. */ @@ -258,6 +297,20 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis } } + private static final int getLevel(WXEmbed embed){ + String priority = embed.priority; + String strategy = embed.strategy; + int level = 5; + if(!STRATEGY_HIGH.equals(strategy)) { + if (TextUtils.equals(priority, PRIORITY_LOW)) { + level = 0; + } else if (TextUtils.equals(priority, PRIORITY_HIGH)) { + level = 10; + } + } + return level; + } + private WXSDKInstance createInstance() { WXSDKInstance sdkInstance = getInstance().createNestedInstance(this); getInstance().addOnInstanceVisibleListener(this); @@ -293,35 +346,85 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis public void setVisibility(String visibility) { super.setVisibility(visibility); boolean visible = TextUtils.equals(visibility, Constants.Value.VISIBLE); - if (!TextUtils.isEmpty(src) && visible) { - if (mNestedInstance == null) { - loadContent(); - } else { - mNestedInstance.onViewAppear(); + if(mIsVisible != visible){ + + if (!TextUtils.isEmpty(src) && visible) { + if (mNestedInstance == null) { + loadContent(); + } else { + mNestedInstance.onViewAppear(); + } } - } - if (!visible) { - if (mNestedInstance != null) { - mNestedInstance.onViewDisappear(); + if (!visible) { + if (mNestedInstance != null) { + mNestedInstance.onViewDisappear(); + } } + mIsVisible = visible; + doAutoEmbedMemoryStrategy(); } - mIsVisible = visible; } @Override public void destroy() { super.destroy(); - if (mNestedInstance != null) { - mNestedInstance.destroy(); - mNestedInstance = null; - } + destoryNestInstance(); src = null; if (getInstance() != null) { getInstance().removeOnInstanceVisibleListener(this); } } + + private void doAutoEmbedMemoryStrategy(){ + /** + * auto manage embed amount in current instance, save memory + * */ + if(!STRATEGY_NONE.equals(this.strategy)){ + if(!mIsVisible && mNestedInstance != null){ + if(PRIORITY_LOW.equals(this.priority)){ + destoryNestInstance(); + }else{ + if(getInstance().hiddenEmbeds == null){ // low is in front, when priority is same, hidden time pre in first + getInstance().hiddenEmbeds = new PriorityQueue<>(8, new Comparator() { + @Override + public int compare(WXEmbed o1, WXEmbed o2) { + int level = getLevel(o1) - getLevel(o2); + if(level != 0){ + return level; + } + return (int) (o1.hiddenTime - o2.hiddenTime); + } + }); + } + //getInstance().hiddenEmbeds.remove(this); + if(!getInstance().hiddenEmbeds.contains(this)) { + this.hiddenTime = System.currentTimeMillis(); + getInstance().hiddenEmbeds.add(this); + } + if(getInstance().hiddenEmbeds != null && getInstance().getMaxHiddenEmbedsNum() >= 0){ + while (getInstance().hiddenEmbeds.size() > getInstance().getMaxHiddenEmbedsNum()){ + WXEmbed embed = getInstance().hiddenEmbeds.poll(); + if(embed.mIsVisible){ + continue; + } + if(embed != null) { + embed.destoryNestInstance(); + } + } + } + } + } + if(mIsVisible && mNestedInstance != null){ + if(getInstance().hiddenEmbeds != null && getInstance().hiddenEmbeds.contains(this)){ + getInstance().hiddenEmbeds.remove(this); + } + } + } + + } + @Override public void onAppear() { //appear event from root instance will not trigger visibility change @@ -381,4 +484,23 @@ public class WXEmbed extends WXDiv implements WXSDKInstance.OnInstanceVisibleLis mNestedInstance.onActivityDestroy(); } } + + public void setStrategy(String strategy) { + this.strategy = strategy; + } + + private void destoryNestInstance(){ + if(getInstance().hiddenEmbeds != null && getInstance().hiddenEmbeds.contains(this)){ + getInstance().hiddenEmbeds.remove(this); + } + if (mNestedInstance != null) { + mNestedInstance.destroy(); + mNestedInstance = null; + } + if(WXEnvironment.isApkDebugable()){ + WXLogUtils.w("WXEmbed destoryNestInstance priority " + priority + " index " + getDomObject().getAttrs().get("index") + + " " + hiddenTime + " embeds size " + (getInstance().hiddenEmbeds == null ? 0 : getInstance().hiddenEmbeds.size()) + + " strategy " + this.strategy); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b582c193/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java index 0d3e477..635b8e4 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXVContainer.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.support.annotation.RestrictTo; import android.support.annotation.RestrictTo.Scope; +import android.support.v4.view.ViewCompat; import android.util.Pair; import android.support.annotation.Nullable; import android.util.Pair; @@ -30,9 +31,12 @@ import android.view.View; import android.view.ViewGroup; import com.taobao.weex.WXSDKInstance; +import com.taobao.weex.annotation.JSMethod; import com.taobao.weex.common.Constants; import com.taobao.weex.dom.WXDomObject; +import com.taobao.weex.ui.view.WXImageView; import com.taobao.weex.utils.WXLogUtils; +import com.taobao.weex.utils.WXUtils; import com.taobao.weex.utils.WXViewUtils; import java.util.ArrayList; @@ -486,6 +490,77 @@ public abstract class WXVContainer extends WXComponent { super.onRenderFinish(state); } + @JSMethod + public void releaseImageList(String viewTreeRecycle){ + if(getHostView() == null + || !ViewCompat.isAttachedToWindow(getHostView()) + || !(getHostView() instanceof ViewGroup)){ + return; + } + boolean isViewTree = WXUtils.getBoolean(viewTreeRecycle, false); + if(isViewTree){ + doViewTreeRecycleImageView(getHostView(), true); + }else{ + int count = getChildCount(); + for(int i=0; i embeds = new PriorityQueue<>(8, new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o1 - o2; + } + }); + + + embeds.add(10); + embeds.add(9); + embeds.offer(1); + + embeds.offer(2); + embeds.add(11); + + System.out.println(embeds.peek() + " " + embeds.size()); + + System.out.println(embeds.poll() + " " + embeds.size()); + } +}