A bloody incident caused by SwipeRefreshLayout

A bloody incident caused by SwipeRefreshLayout

[[185980]]

As for the pull-down refresh, both ordinary users and developers are familiar with it. In the past, both the pull-down refresh design and the open source control were extremely popular, so popular that it alarmed the Party Central Committee (Google), so the Party Central Committee added a pull-down refresh control in the support package - SwipeRefreshLayout. The pull-down effect is very unique and can be called low-key and gorgeous. Here is a picture first. I believe everyone is familiar with it. As for how to use SwipeRefreshLayout, I won’t explain it. If you don’t know it, go to face the wall.

Swiperefreshlayout.gif

As a staunch supporter of Material Design, I also used SwipeRefreshLayout in practice. I simply wrote a BaseSwipeRefreshLayout class to initialize some basic properties. Because it is easy to use, I didn't do too much encapsulation. If I need to use pull-down refresh, I directly reference this Base class in the layout, but I didn't expect that it would bury a pit and cause a bloody case. Of course, it's not that there is any error in the code of the Base class itself, but because of some strange combinations that caused some bloody bugs, let me continue to talk about it.

In actual development, basically all Activities and Fragments use this pull-down refresh. My homepage is a classic design in which an Activity maintains 4 Fragments through ViewPager. The first and second pages use pull-down refresh, and Fragments use lazy loading. For lazy loading, you can read my other article ViewPager+Fragment LazyLoad*** Solution. There will be no problem with this code, and everything looks so beautiful! Rejoice, that's how confident you are. However, one day I suddenly discovered an inexplicable phenomenon: when I started the App and stayed on the first page, even if it was still, the CPU utilization was still very high, and very linear, with almost no fluctuations. When I switched to the second page, after the data was loaded, the CPU utilization went down immediately. I laughed at that time.

So I started to troubleshoot and optimize. After a simple analysis, I was basically sure that the problem was on the second page. Unfortunately, the layout of my second page was very complicated. There was an automatic carousel at the top, followed by two horizontal RecyclerViews, and finally a vertical RecyclerView. Of course, there were some small views nested in between. Let's analyze the problem again: when I entered the App and stopped at the homepage, because of lazy loading, the View of the second page had been initialized, but it had not loaded Data. At this time, the CPU utilization rate was very high. When I switched to the second page and loaded Data, the CPU utilization rate immediately returned to normal. And if I didn't use lazy loading to load Fragment, there would be no problem. So first of all, I suspected that there was something wrong with my lazy loading. I debugged it and found that everything was normal and there was nothing unreasonable.

According to the experience of the old driver, since the CPU has been high, it is very likely that a certain view has been measuring and calculating. The most suspicious here is RecyclerView, but I have three RecyclerViews here. I can only use the elimination method, comment them out one by one and then observe the CPU situation. However, surprisingly, even if I comment them all out, it doesn’t work. It seems that the problem is not caused by repeated measurement of View. At this time, the spearhead is directly pointed at the large carousel at the top. The carousel can scroll automatically and loop continuously. It may be that the control is not reasonable somewhere, or there is a problem with the timer. It seems that I have seen the light, and the problem should be here, so I commented out the carousel and looked again. Oh, it still doesn’t work.

The problem seems to be stuck. According to the normal plot development, I should go downstairs to light a cigarette, communicate with my colleagues while smoking, then take a deep breath, exhale the light blue smoke, watch the blue smoke slowly rise, think hard, and suddenly shout: I know. Then I put out the cigarette butt fiercely and ran upstairs, leaving my colleagues in a mess in the smoke. But the actual situation is: I don't smoke. Since I can't quickly locate the problem based on subjective experience at this time, I can only use a stupid way. Still using the elimination method, I commented out all the suspicious codes line by line. At the end, I almost commented out the entire class. After debugging, there was no code to execute, only a layout was loaded. But I don't want to say but anymore.

After checking all the JAVA code, I still couldn't locate the problem. I was a little worried. Was it a layout problem? OverDraw? Everything was just speculation. I could only try to eliminate the problem View by View. However, I never expected that the culprit was the BaseSwipeRefreshLayout I wrote above. I had to fill the hole I dug myself.

  1. public class BaseSwipeRefreshLayout extends SwipeRefreshLayout {
  2.  
  3.   
  4.  
  5. public BaseSwipeRefreshLayout(Context context) {
  6.  
  7. super(context);
  8.  
  9. init();
  10.  
  11. }
  12.  
  13.   
  14.  
  15. public BaseSwipeRefreshLayout(Context context, AttributeSet attrs) {
  16.  
  17. super(context, attrs);
  18.  
  19. init();
  20.  
  21. }
  22.  
  23.   
  24.  
  25. private void init() {
  26.  
  27.   
  28.  
  29. this.setProgressViewOffset( false , DensityUtil.dip2px(getContext(), -50), DensityUtil.dip2px(getContext(), 30));
  30.  
  31. this.setColorSchemeColors(getContext().getResources().getColor(R.color.primary_green));
  32.  
  33. setRefreshing( true );
  34.  
  35. }
  36.  
  37.   
  38.  
  39. @Override
  40.  
  41. public boolean onStartNestedScroll( View child, View target, int nestedScrollAxes) {
  42.  
  43. return !isRefreshing() && super.onStartNestedScroll(child, target, nestedScrollAxes);
  44.  
  45. }
  46.  
  47. }

The above class has only a few lines, and just does some uniform initialization operations, but it causes some problems. Can you see the problem in three minutes?

The problem lies in the sentence setRefreshing(true); in the init() method. When I wrote it, I thought that loading would be required as soon as the interface entered, so I might as well add loading to Base. This way, I don’t have to write it again for each interface. But because I used lazy loading in the above scenario, the problem came: although I stayed on the first page, the View of the second page had been initialized, so naturally the loading circle of SwipeRefreshLayout was already spinning, so the CPU began to be very linear and high. Switching to the second page, after the data loading was completed, setRefreshing(false), the loading circle disappeared, and the CPU returned to normal. It took a lot of effort, but fortunately, the pit was filled in the first place. Another unexpected point is that it turns out that SwipeRefreshLayout is not very fuel-efficient.

The difficulty in the actual development process is not how to solve the problem, but how to troubleshoot and locate the problem. In most cases, we can quickly locate the problem based on our own accumulation and experience. But the pit I dug this time was really hidden, and it took a lot of effort to check almost line by line from JAVA code to Xml, and finally filled the pit. So we still need to consider more comprehensively in development and dig fewer pits. If we really find a pit, there are also routines to find. Carefully analyze the problem and check it step by step from JAVA code to XML, and it will always be clear.

<<:  Will Android become history? Google is launching a new operating system

>>:  Heartbeat Journey - iOS uses the phone camera to detect heart rate (PPG)

Recommend

CATL vs BYD: Who will be the final winner?

Another daily limit, another daily limit! After t...

Will there be a winner in the ongoing battle between Xiaomi and LeTV?

Among the major Internet companies, the "gru...

How much does it cost to develop a Shuangyashan flower mini program?

Shuangyashan flower mini program investment promo...

Can eye protection lamps prevent myopia?

"Doctor, is the eye protection lamp useful? ...

Your brain works harder than you think to tell you the order of time

In our perception, time is an invisible and intan...

Carrying the weight forward: the magical function of exoskeleton equipment

A normal adult has 206 bones in his body, and our...

Samsung S5's powerful fingerprint function sharing

Samsung's new flagship GALAXY S5 has brought g...

A set of high conversion and traffic generation course SOP

Lead-in courses are a common marketing method ado...

How to publish multiple articles on WeChat subscription account?

How to publish multiple articles on WeChat subscr...