DeepAndroid intends to summarize what it has done in the business over the years
Github.com/loganpluo/D…
1. Routine operation
(1) Layout optimization
- Layer reduction: Merge, viewStub lazy loading, and reduce redundant layers.
- Reduced number of Views: TextView span to replace useless views
- View can determine the size as much as possible, avoid measure: picture size, item height
- Avoid transition drawing: Backgroud overlap can remove useless ones
- Reduce inflater time: Easy to write layouts can replace XML. (That’s true, but often handwritten layouts are not as efficient as XML development, and are more scalable and maintainable. Google has created Jetpack Compose.
(2) ASYNCHRONization of CPU-intensive operations
- The data in onBindViewHolder is used directly for presentation, avoiding CPU intensive operations such as time format conversion, parsing expression, json parsing, etc
(3) Avoid frequent new objects, which may consume resources and trigger frequent gc collection
For example, addXxListener performs different operations based on the ID, rather than new XxListener each time
(4) Stop other threads during scrolling to avoid competing with the main thread for CPU resources
Stop loading images (if the product accepts)
2. Other optimizations (which I haven’t done before)
(1) Update of diffUtil
DiffUtil gets usage, can oneself go on the net search, my result summary
- Currently adding data and update data to the insert tail does perform better than all NotifyDatachange update renderings at frame rates;
- But in the header insert data, the DiffUtil triggered update has some extra refresh recyclerView operation, resulting in the frame rate of rendering is not good, this place is still tracking the reason;
- In addition, it is better to transfer diffUtil calculation to asynchronous threads to avoid slow calculation as data increases.
DiffUtil does increase the refresh frame rate, and does have some development costs if you want to refine the UI diff variations for each field, as follows:
- You write the field equality logic by hand, then payloads the changing field to trigger UI refresh of the corresponding field (I’m going to use field reflection and dynamic binding to simplify this process later)
- The object of the new data set must be renewed, even if the value of a field is changed (e.g. In your message list, the status of a message changes to “sent successfully”. You need to create a new object and change state to “succeeded” to diff the value of the state field in the new object and trigger stateView refresh.
(2) Expand the cache pool of Viewholder of recyclerView to exchange space for time
For example, in the message list, the viewholder of the text and image types are used the most, so I expanded to 10 for those types, and the default was 5
RecyclerView.recycledViewPool.setMaxRecycledViews(int viewType, int max)
Copy the code
(3) If it is the form of multiple tabs, you can use a recyclerView of recycledViewPool cache pool, so that cutting tabs can be faster
(4) Better performance of the customized view components
- Customizing textView (not yet, because textView has GIF emoji nested inside it)
Reference: juejin. Cn/post / 684490…
Github.com/SusionSuc/A…