preface

After paving the way for the previous two articles on Paging, now I would like to share with you how to apply the idea of Paging in the starting point reading.

Why thoughts?

Because Paging 2 is a stable version at the present stage, it is difficult to use, while Paging 3 is relatively easy to use, BUT I still dare not use it in Alpha state in our production environment, and there are still some obstacles when it is combined with specific businesses.

The background,

Since I started reading articles, I have been iterating on the business of reading community. When BROWSING weibo, the benchmark of community business, I found that when browsing the list of weibo, it would rarely slide to the bottom of data and then Loading state, which should be preloading data.

When our App slides to the bottom of the data, Loading state will occur:

With the preload solution, users are not aware of the wait caused by sliding the bottom of the data to initiate a web request, and the whole browsing process is more smooth, so I plan to apply this technology to our community business.

2. Program selection

Paging in Android Jetpack has the function of pre-loading data. However, as mentioned above, both Paging 2 and Paging 3 have certain pain points. Let’s analyze them in detail.

The problem with Paging 2 is still obvious:

  1. The API is really hard to use: different data sources need to be used for different scenarios.
  2. No state management: This means that when data is loaded, it is difficult to listen for the status of requests and update the corresponding UI.

Paging 3 solves the above problems, but it is still in Alpha, which forces me to abandon it, and even if it is plugged in, it has the following problems:

  1. RecyclerViewAdapterConflict: The belief that everyone’s business encapsulates their ownAdapter, whether using inheritance or directly using Paing 3PagingDataAdapterIt’s difficult.
  2. Data interface problem: When defining an interface, it rarely returns only a list of data. It also returns some other information. Take our business as an example, when returning a list of posts, it also returns information about the circle.

Based on these questions, we built a wheel QDPaging.

Three, the frame structure

1. Basic functions

Before building the wheel, we needed to understand the basic requirements of the business. Our starting point was simple: data preloading and state management.

1.1 Status Management

State management is used to interact with the UI, and QDPaing borrows directly from Paging 3’s state structure.

Corresponding to:

  • Refresh: Refresh the scene
  • Append: Load more
  • Prepend: Loads data forward

It should be noted that I used two basic adapters, one that can limit the amount of capacity, and one that has no limit, which is not Prepend (forward loading).

1.2 Data Preloading

Unlike Paging 3, for project and other reasons, QDPaging data loading does not use coroutines and flows, but instead uses thread pools + LiveData in Paging 2.

When does preloading happen?

  1. When binding data: because theAdapterIt will be called every time we need to bind datagetItemMethod, after meeting certain conditions, it will start.
  2. loadMore: ourRecyclerVIewThey’re all encapsulated, so every time you slide to the bottom, you trigger oneloadMoreMethod, which also triggers preloading.
  3. Refresh: The scenario of refreshing data.

The loading process looks like this:

2. Other functions

After the basic requirements were satisfied, I added some additional features.

2.1 Transfer of data outside the list

When the interface is defined in the list page, there is usually some extra data attached, and you may be faced with the choice between one interface and two interfaces:

  • One interface: Consolidate data into one interface.
  • Two interfaces: the list data goes through one interface, and other information goes through one interface. However, this increases the workload and may bring two refreshes, which is unbearable for visual students.

In the end, an interface is usually selected, but this approach may not be very friendly for the Paging library mentioned earlier, but there are solutions.

How does QDPaging solve this problem? In simple terms, it is a layer of data encapsulation, including the data, and store a member variable of type Any, equivalent to Object in Java. When you implement your data source, you can store other data in the member variable of Any, and use LiveData to send back.

2.2 Data Capacity Limitation

The purpose of the data capacity limit is to facilitate memory control.

To control data volume, QDPaging uses a bidirectional linked list, where a page of data is a node that records the current data, the page number, the previous node, and the next node.

When the data capacity exceeds the threshold, backward loading will throw out the preceding nodes, forward loading will throw out the following nodes, and finally realize the quantity control.

2.3 Reducing code

In combination with the inherent Ui components of the starting point book, some events are added automatically:

  • Automatic initiation of requests to refresh, load more, etc.
  • List control for loading state (weak network, no network will be displayed), refresh state and normal data state automatic switch.
  • Error handling.

So, in some paging scenarios, we now just have to implement a data source class, tell the system what the next and previous page numbers are, and finally bind the UI components, and possibly deal with scenarios other than listing data.

Overall, you can reduce some of the code you normally have to write.

Iv. Results and benefits

Let’s call the loading of the request caused by sliding onto the data tail a valid loading wait scenario. Let’s look at the effect before and after optimization.

Before optimization The optimized

QDPaging did reduce the number of valid waiting to load scenarios, and the results were what I expected:

version Effective waiting times per capita (times)
7.9.76 4.485
7.9.78 0.015

Decreased effective waiting load scenarios by 99%. Of course, preloading does not help in weak or no-network situations.

In addition, our preloaded library can:

  • Effectively reduce logical code.
  • In combination withAndroid JetpackIn theLiveDataLifecycleTo reduce crashes caused by component life cycles.
  • Limit data capacity to limit memory.

conclusion

Although we have achieved the results we wanted, there is still a lot of work to do:

  1. The paging library, while a little too coupled to the starting UI component, needs to be decoupled.
  2. At present, the preloading function only lands on the attention list page of the discovery page of the starting point, and more pages will be promoted in the future.

Android Jetpack, Google’s latest Android rapid development tool set, has a lot to learn. For example, most of the functions of our preloaded library are borrowed from the Paging library in Android Jetpack and use LiveData and Liftcycle in Android Jetpack.

Using just one of the libraries in Android Jetpack might be the same experience as other libraries with the same function, but using several of these libraries in combination is a huge and exciting scene. Starting in agile mode in the first half of last year, if you want to go faster, We will introduce more Android Jetpack components in the future.

advertising

If I think this article is good, the third line is the biggest encouragement to my creation ~

I am Jiuxin, welcome to follow my public account jiuxin said to receive my latest articles. Or add my wechat JiuXinDev, pull you into the group, along with me on the Android road to progress ~