Defer MessagingMessage#recycle until bind ends
See ag/17158486 for context.
Fixes: 216202070
Test: manual
Change-Id: I924f917fbf757d2c3866fcd60de2fbfccae2eb6a
Merged-In: I924f917fbf757d2c3866fcd60de2fbfccae2eb6a
(cherry picked from commit 88f4dbce89)
This commit is contained in:
@@ -66,7 +66,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
|
||||
@@ -76,8 +75,6 @@ import java.util.function.Consumer;
|
||||
public class ConversationLayout extends FrameLayout
|
||||
implements ImageMessageConsumer, IMessagingLayout {
|
||||
|
||||
private static final Consumer<MessagingMessage> REMOVE_MESSAGE
|
||||
= MessagingMessage::removeMessage;
|
||||
public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
|
||||
public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
|
||||
public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
|
||||
@@ -150,7 +147,7 @@ public class ConversationLayout extends FrameLayout
|
||||
private Icon mShortcutIcon;
|
||||
private View mAppNameDivider;
|
||||
private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
|
||||
private ArrayList<MessagingGroup> mToRecycle = new ArrayList<>();
|
||||
private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
|
||||
|
||||
public ConversationLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -463,8 +460,12 @@ public class ConversationLayout extends FrameLayout
|
||||
removeGroups(oldGroups);
|
||||
|
||||
// Let's remove the remaining messages
|
||||
mMessages.forEach(REMOVE_MESSAGE);
|
||||
mHistoricMessages.forEach(REMOVE_MESSAGE);
|
||||
for (MessagingMessage message : mMessages) {
|
||||
message.removeMessage(mToRecycle);
|
||||
}
|
||||
for (MessagingMessage historicMessage : mHistoricMessages) {
|
||||
historicMessage.removeMessage(mToRecycle);
|
||||
}
|
||||
|
||||
mMessages = messages;
|
||||
mHistoricMessages = historicMessages;
|
||||
@@ -475,8 +476,8 @@ public class ConversationLayout extends FrameLayout
|
||||
updateConversationLayout();
|
||||
|
||||
// Recycle everything at the end of the update, now that we know it's no longer needed.
|
||||
for (MessagingGroup group : mToRecycle) {
|
||||
group.recycle();
|
||||
for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
|
||||
child.recycle();
|
||||
}
|
||||
mToRecycle.clear();
|
||||
}
|
||||
|
||||
@@ -263,7 +263,8 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
return createdGroup;
|
||||
}
|
||||
|
||||
public void removeMessage(MessagingMessage messagingMessage) {
|
||||
public void removeMessage(MessagingMessage messagingMessage,
|
||||
ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
|
||||
View view = messagingMessage.getView();
|
||||
boolean wasShown = view.isShown();
|
||||
ViewGroup messageParent = (ViewGroup) view.getParent();
|
||||
@@ -271,15 +272,14 @@ public class MessagingGroup extends LinearLayout implements MessagingLinearLayou
|
||||
return;
|
||||
}
|
||||
messageParent.removeView(view);
|
||||
Runnable recycleRunnable = () -> {
|
||||
messageParent.removeTransientView(view);
|
||||
messagingMessage.recycle();
|
||||
};
|
||||
if (wasShown && !MessagingLinearLayout.isGone(view)) {
|
||||
messageParent.addTransientView(view, 0);
|
||||
performRemoveAnimation(view, recycleRunnable);
|
||||
performRemoveAnimation(view, () -> {
|
||||
messageParent.removeTransientView(view);
|
||||
messagingMessage.recycle();
|
||||
});
|
||||
} else {
|
||||
recycleRunnable.run();
|
||||
toRecycle.add(messagingMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ import com.android.internal.util.ContrastColorUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A custom-built layout for the Notification.MessagingStyle allows dynamic addition and removal
|
||||
@@ -62,8 +61,6 @@ public class MessagingLayout extends FrameLayout
|
||||
implements ImageMessageConsumer, IMessagingLayout {
|
||||
|
||||
private static final float COLOR_SHIFT_AMOUNT = 60;
|
||||
private static final Consumer<MessagingMessage> REMOVE_MESSAGE
|
||||
= MessagingMessage::removeMessage;
|
||||
public static final Interpolator LINEAR_OUT_SLOW_IN = new PathInterpolator(0f, 0f, 0.2f, 1f);
|
||||
public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
|
||||
public static final Interpolator FAST_OUT_SLOW_IN = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
|
||||
@@ -89,6 +86,7 @@ public class MessagingLayout extends FrameLayout
|
||||
private boolean mIsCollapsed;
|
||||
private ImageResolver mImageResolver;
|
||||
private CharSequence mConversationTitle;
|
||||
private ArrayList<MessagingLinearLayout.MessagingChild> mToRecycle = new ArrayList<>();
|
||||
|
||||
public MessagingLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -212,8 +210,12 @@ public class MessagingLayout extends FrameLayout
|
||||
removeGroups(oldGroups);
|
||||
|
||||
// Let's remove the remaining messages
|
||||
mMessages.forEach(REMOVE_MESSAGE);
|
||||
mHistoricMessages.forEach(REMOVE_MESSAGE);
|
||||
for (MessagingMessage message : mMessages) {
|
||||
message.removeMessage(mToRecycle);
|
||||
}
|
||||
for (MessagingMessage historicMessage : mHistoricMessages) {
|
||||
historicMessage.removeMessage(mToRecycle);
|
||||
}
|
||||
|
||||
mMessages = messages;
|
||||
mHistoricMessages = historicMessages;
|
||||
@@ -223,6 +225,12 @@ public class MessagingLayout extends FrameLayout
|
||||
// after groups are finalized, hide the first sender name if it's showing as the title
|
||||
mPeopleHelper.maybeHideFirstSenderName(mGroups, mIsOneToOne, mConversationTitle);
|
||||
updateImageMessages();
|
||||
|
||||
// Recycle everything at the end of the update, now that we know it's no longer needed.
|
||||
for (MessagingLinearLayout.MessagingChild child : mToRecycle) {
|
||||
child.recycle();
|
||||
}
|
||||
mToRecycle.clear();
|
||||
}
|
||||
|
||||
private void updateImageMessages() {
|
||||
@@ -263,18 +271,17 @@ public class MessagingLayout extends FrameLayout
|
||||
MessagingGroup group = oldGroups.get(i);
|
||||
if (!mGroups.contains(group)) {
|
||||
List<MessagingMessage> messages = group.getMessages();
|
||||
Runnable endRunnable = () -> {
|
||||
mMessagingLinearLayout.removeTransientView(group);
|
||||
group.recycle();
|
||||
};
|
||||
|
||||
boolean wasShown = group.isShown();
|
||||
mMessagingLinearLayout.removeView(group);
|
||||
if (wasShown && !MessagingLinearLayout.isGone(group)) {
|
||||
mMessagingLinearLayout.addTransientView(group, 0);
|
||||
group.removeGroupAnimated(endRunnable);
|
||||
group.removeGroupAnimated(() -> {
|
||||
mMessagingLinearLayout.removeTransientView(group);
|
||||
group.recycle();
|
||||
});
|
||||
} else {
|
||||
endRunnable.run();
|
||||
mToRecycle.add(group);
|
||||
}
|
||||
mMessages.removeAll(messages);
|
||||
mHistoricMessages.removeAll(messages);
|
||||
|
||||
@@ -365,6 +365,7 @@ public class MessagingLinearLayout extends ViewGroup {
|
||||
default int getExtraSpacing() {
|
||||
return 0;
|
||||
}
|
||||
void recycle();
|
||||
}
|
||||
|
||||
public static class LayoutParams extends MarginLayoutParams {
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.app.ActivityManager;
|
||||
import android.app.Notification;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -96,8 +97,8 @@ public interface MessagingMessage extends MessagingLinearLayout.MessagingChild {
|
||||
return sameAs(message.getMessage());
|
||||
}
|
||||
|
||||
default void removeMessage() {
|
||||
getGroup().removeMessage(this);
|
||||
default void removeMessage(ArrayList<MessagingLinearLayout.MessagingChild> toRecycle) {
|
||||
getGroup().removeMessage(this, toRecycle);
|
||||
}
|
||||
|
||||
default void setMessagingGroup(MessagingGroup group) {
|
||||
|
||||
Reference in New Issue
Block a user