Add CachedLayoutInflater to improve conversation render performance.

This commit is contained in:
Greyson Parrelli
2020-05-08 12:34:32 -04:00
committed by Alex Hart
parent 7fd3bfa30c
commit ed33e048ad
6 changed files with 171 additions and 5 deletions

View File

@@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.CachedInflater;
import org.thoughtcrime.securesms.util.Conversions;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
@@ -171,8 +172,7 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
case MESSAGE_TYPE_UPDATE:
long start = System.currentTimeMillis();
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
V itemView = ViewUtil.inflate(inflater, parent, getLayoutForViewType(viewType));
V itemView = CachedInflater.from(parent.getContext()).inflate(getLayoutForViewType(viewType), parent, false);
itemView.setOnClickListener(view -> {
if (clickListener != null) {
@@ -197,7 +197,7 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
return new PlaceholderViewHolder(v);
case MESSAGE_TYPE_HEADER:
case MESSAGE_TYPE_FOOTER:
return new HeaderFooterViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.cursor_adapter_header_footer_view, parent, false));
return new HeaderFooterViewHolder(CachedInflater.from(parent.getContext()).inflate(R.layout.cursor_adapter_header_footer_view, parent, false));
default:
throw new IllegalStateException("Cannot create viewholder for type: " + viewType);
}
@@ -417,7 +417,19 @@ public class ConversationAdapter<V extends View & BindableConversationItem>
}
}
/**
* Provided a pool, this will initialize it with view counts that make sense.
*/
@MainThread
static void initializePool(@NonNull RecyclerView.RecycledViewPool pool) {
pool.setMaxRecycledViews(MESSAGE_TYPE_INCOMING, 15);
pool.setMaxRecycledViews(MESSAGE_TYPE_OUTGOING, 15);
pool.setMaxRecycledViews(MESSAGE_TYPE_PLACEHOLDER, 15);
pool.setMaxRecycledViews(MESSAGE_TYPE_HEADER, 1);
pool.setMaxRecycledViews(MESSAGE_TYPE_FOOTER, 1);
pool.setMaxRecycledViews(MESSAGE_TYPE_UPDATE, 5);
}
private void cleanFastRecords() {
synchronized (releasedFastRecords) {
Iterator<MessageRecord> recordIterator = fastRecords.iterator();

View File

@@ -36,6 +36,7 @@ import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;
@@ -105,6 +106,7 @@ import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.stickers.StickerLocator;
import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity;
import org.thoughtcrime.securesms.util.CachedInflater;
import org.thoughtcrime.securesms.util.CommunicationActions;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.HtmlUtil;
@@ -161,6 +163,16 @@ public class ConversationFragment extends Fragment {
private MessageRequestViewModel messageRequestViewModel;
private ConversationViewModel conversationViewModel;
public static void prepare(@NonNull Context context) {
FrameLayout parent = new FrameLayout(context);
parent.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT));
CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_received, parent, 10);
CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_sent, parent, 10);
CachedInflater.from(context).cacheUntilLimit(R.layout.conversation_item_update, parent, 5);
CachedInflater.from(context).cacheUntilLimit(R.layout.cursor_adapter_header_footer_view, parent, 2);
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -413,6 +425,7 @@ public class ConversationFragment extends Fragment {
ConversationAdapter adapter = new ConversationAdapter(GlideApp.with(this), locale, selectionClickListener, this.recipient.get());
list.setAdapter(adapter);
list.addItemDecoration(new StickyHeaderDecoration(adapter, false, false));
ConversationAdapter.initializePool(list.getRecycledViewPool());
setLastSeen(conversationViewModel.getLastSeen());

View File

@@ -236,8 +236,6 @@ public class ConversationItem extends LinearLayout implements BindableConversati
bodyText.setOnLongClickListener(passthroughClickListener);
bodyText.setOnClickListener(passthroughClickListener);
bodyText.setMovementMethod(LongClickMovementMethod.getInstance(getContext()));
}
@Override
@@ -522,6 +520,7 @@ public class ConversationItem extends LinearLayout implements BindableConversati
bodyText.setClickable(false);
bodyText.setFocusable(false);
bodyText.setTextSize(TypedValue.COMPLEX_UNIT_SP, TextSecurePreferences.getMessageBodyTextSize(context));
bodyText.setMovementMethod(LongClickMovementMethod.getInstance(getContext()));
if (messageRecord.isRemoteDelete()) {
String deletedMessage = context.getString(R.string.ConversationItem_this_message_was_deleted);