Realize high-performance WeChat Moments

As we all know, the list of WeChat Moments has always been used as a model by many friends who study performance issues. It has always been a bit difficult to compare its implementation. I can only silently sigh that the developers of WeChat are really awesome. After a period of research, I will now lead you to analyze the structure of WeChat Moments with a new understanding and realize it in your own way. First picture:

20180503_222857.gif

GIF looks a bit stuck, you can download the apk to experience it yourself, the fluency is almost the same as WeChat: app-debug.apk

Source address: HighPerformanceFriendsCircle

We all know that in Android, for lists, to avoid stuttering, we can optimize from the following angles.

1. Reduce the layout level and avoid too many useless layout nesting of Item View. 2. For a list with pictures, it is necessary to control the pictures when sliding, that is, the pictures are not loaded when sliding, and the pictures are loaded after stopping the sliding. 3. It should be avoided to do too much calculation or nest too many logical judgments when filling data in Adapter. For complex calculation results, the calculation should be completed before the Adapter fills the data.

The above are some basic optimizations for a common Adapter, and for a complex list like WeChat Moments, in addition to the above, other aspects need to be optimized. For example, it includes reducing the repeated creation of Views, building cached Views, and reducing the number of onMeasure and onLayout layouts. These are especially important. Let's briefly analyze the view structure of each item in some WeChat lists. By analyzing WeChat, we can understand some of our own solutions.

First, we use the Android Device Monitor view analyzer to analyze the view structure of each Item in the WeChat Moments.

From the figure, we can know that the outermost part of its Item is a FramLayout, and the contents inside are some common Views. The key point is the construction of the comment list. We know that WeChat comments are displayed directly in the list. Here we find that its comment list is actually wrapped with a LinearLayout. Due to the uncertainty of each dynamic comment, we need to continuously create comment Views and remove redundant Views in the adapter, which involves performance issues, so how exactly does WeChat display multiple comments in one Item? What about obvious stuttering?

In ViewGroup, there is a method that may have been ignored by everyone. It is addViewInLayout(). Since it is declared protected, the subclasses of external ViewGroup cannot be called directly. To use addViewInLayout(), you must inherit ViewGroup or Subclass ViewGroup and override this method. So what is the use of the addViewInLayout() method? What is the difference between it and our commonly used addView()?

Let's first look at the official explanation of addViewInLayout():

Simple translation: Add views to your layout. This is useful if in the onLayout() method you need to add more views (e.g. list views). If the index is negative, it means to put it at the end of the list.

This doesn't seem like anything special, but where it's really useful is the preventRequestLayoutparameter in the method, which is a boolean, but it's really useful. If true, it will not trigger layout requests for child objects when a View is added. That is to say, the onMeasure and onLayout operations will not be triggered when the View is added. Official api explanation diagram:

H

Through the analysis of addViewInLayout(), I think you probably understand that since you don't need to trigger onMeasure() and onLayout() when adding View dynamically, it will save a lot of adapter refresh speed. As mentioned above, among the performance points of the adapter, it is particularly important to reduce the onMeasure and onLayout of the adapter Item (because in fact the display of the View onMeasure and onLayout takes a lot of time).

Similarly, when removing a View, we can use removeViewInLayout(), which has the same effect as addViewInLayout(). Therefore, with this approach, we solve the performance issue of dynamically changing updates of the comment list.

The display of Jiugongge pictures can only be achieved by customizing the ViewGroup, which is still the addition and removal of ImageView. Similarly, we can use the methods addViewInLayout() and removeViewInLayout() to reduce onMeasure() and onLayout(). times to save performance costs.

The optimization in other aspects is to complete various data transformation operations in the data bean, including complex calculations, such as converting String into the required SpannableStringBuilder.

Finally, in addition to reducing the number of onMeasure() and onLayout(), we also need to reduce the creation of View. To reduce the creation of Views, we can use a cached array of weak references and implement the caching of View objects, thanks to the idea provided by razerdp .

For some other specific logic, you can study it yourself in the code, and you may continue to update the project in the future, including the matching of expressions, matching of phone numbers, etc., depending on your own time. Welcome everyone to start!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325340221&siteId=291194637