Welcome to follow my official account, scan the qr code below or search the official id: MXSZGG

  • preface
  • YiHuan
  • The second delay
  • Four slow
  • other
    • Talk about BindView (1)
    • Talk about BindView (2)

preface

Before the topic, I still want to say a few words, and the same as before, the article does not involve source code, the default readers have a certain understanding of the source code, the reason for writing as before, because I think the current in the ListView/RecyclerView source code to explain the article, mostly to the source code crackling, It is somewhat difficult to understand, so the author would like to visualize some data, hand to lead readers to understand the implementation of the cache mechanism, and recommend reading Tencent Bugly “Android ListView and RecyclerView comparison analysis – cache mechanism” article.

1. Previous address: “Visual ListView caching mechanism, touch your hand to take you through the Ren Di two veins”

2. This article project address: RecyclerViewVisualization or directly download the apk

Please read this article before you read it. Some of the keywords in this article are mentioned above.

YiHuan

Touch your hand to open app:

The functions of mAttachedScrap in RecyclerView and mActiveViews in ListView are basically similar. For quick reuse of items on the screen (RecyclerView/ListView has two onLayout() processes, the second onLayout() directly use the first onLayout() cache View, without creating).

The second delay

In fact, two-buffer mCachedViews and four-buffer RecyclerViewPool together have the same meaning as ListView’s two-buffer mScrapedViews, in order to reuse items that are about to enter the screen. Let’s talk about the second delay in detail:

  • An ArrayList
  • The default size is 2
  • The size variable
  • The reuse algorithm matches whether the ViewHolder position is equal to the position passed in from the tail in reverse order, and returns if the match is successful
  • To optimize the previous step, the next possible item will be placed at the tail

The second buffer is to match the corresponding ViewHolder by position, where position refers to the position of item that may enter the screen predicted by RecyclerView. It is determined by the current screen slide direction and the visible item position. For example, if the screen is swiped down, the position of the item that may enter the screen is position-1 of the first item that is currently visible. If the screen slides up, the position of the item that may enter the screen is the position + 1 of the last item currently visible. This may sound a little vague, but here’s an example:

In this case, if the screen slides, the position that predicts the next possible item on the screen might be 4 (Item1 “E(layoutPosition:4)”). If the screen slides, the position of the next item predicted to appear on the screen is 0 (that is, item “A(layoutPosition:0)”). Position is then compared to the layoutPosition of the ViewHolder in mCacheViews, and the ViewHolder is returned if the same.

Take a look at the GIF:

1. On-screen slide:

You can see that the target mCacheView position changes from 0 to 4. At the same time, mCachedViews adjusts the position of the item that might appear on the screen from its original position to the last bit of the ArrayList.

2. Screen slide:

When the screen slides down, the Target mCachedView position changes from 4 to 0. At the same time, changes will be made to mCachedViews internally.

Four slow

Four cache (RecycledViewPool) nature:

  • A SparseArray is maintained internally

  • The SparseArray key is the ViewType of the ViewHolder, which means that each ViewHolder has its own cache of data

  • SparseArray value is a type of ScrapData, and ScrapData is the key cache data structure.

      static class ScrapData {
          ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
          int mMaxScrap = 5;
          // ...
      }
    Copy the code

So, for each ViewHolder, RecycledViewPool, maintain a default ArrayList of 5 to cache them, and of course, the default ArrayList is limited to 5. This can be changed by RecycledViewPool#setMaxRecycledViews(viewType, Max). Both are fine (which is one reason the data type is ArrayList rather than array).

In fact, two-buffer mCachedViews and four-buffer RecyclerViewPool are the same as ListView’s two-buffer mScrapedViews, for reuse of incoming items. , there may be some friends confused, since the meaning is the same, why not only two slow enough, but also a more complex four slow? Here’s why: RecycledViewPool#putRecycledView(ViewHolder) Technically can realize multiple RecyclerView share the same RecyclerViewPool (RecyclerView#setRecycledViewPool). In my opinion, these two points are an important reason to choose RecyclerView or ListView in some business scenarios. As for the practice of these two points, the first thing the author has been added in the Demo (eggs), the second author here extends, readers can add to RecyclerViewVisualization Demo, the corresponding data will also be displayed on the screen

other

Talk about BindView (versus ListView)

When a View is fully displayed on the screen, it should go through two processes: creating the View and adding data to the View. Therefore, the caching mechanism is not only for caching the View, but also for optimizing the process of adding data. After all, setText() and setImage() can also be time-consuming operations. RecyclerView is optimized for that, and we know that ListView actually caches views, and RecyclerView actually caches ViewHolder, which means that ListView can reuse views, But the process of adding data to a View cannot be reused, and when you reuse a ViewHolder, not only is the View being reused, but the process of adding data to the View is also cached, and that’s what RecyclerView does

We can see that BindViewHolder is not triggered when a ViewHolder is stored and displayed on the screen.

Ps: Of course, this is based on the data source does not change. If the data source changes, you must add data to the View again.

Talk about BindView (partial refresh)

1. Partial refresh:

2. Global refresh:

As you can see, the partial refresh can bind views only for the changed views, while the global refresh can bind views for all views that are affected. So, in everyday use, should you consider using local flushes instead of global flushes?