While running the Ali Cloud compatibility test recently, I found that memory is generally high on some machines. I checked the log to confirm that there is a memory leak, and started to use LeakCanary and located the GC Root with the problem:

It is the leakage of the framework. According to common sense, it should be caused by illegal call of the APP layer. The solution is as follows:

  1. Find the holder.
  2. Find the holder’s theoretical release point.
  3. Find the unexecuted path to the theoretical release point.

Check out this idea:

  1. The owner is clearly the mNewActivities property in the ActivityThread, which is an ActivityClientRecord object with a linked data structure.
  2. This step is where the effort is. It takes a while to scroll through the framework layer source code and discover the theoretical release point, which should be invoked when the ActivityThread object executes the handleResumeActivity function.

3. If there are two activities, A1 and A2, and A1 is below A2, then the chain structure of mNewActivities should be A1 -> A2. Now A2 performs the exit operation,Acti VityManagerServer schedules the life cycles of A1 and A2, calling handleResumeActivity to execute A1’s OnResume and removing A2 from the end of mNewActivities (the logic executed in Idler). So this is normal logic, obviously this process doesn’t work, so where did it go wrong, back to where Idler is executing,

One guess is that the main thread Looper is doing a lot of tasks and has no time to execute addIdleHandler’s tasks, so I’ll see if Looper is busy and add code to A1’s onCreate

Sure enough, a lot of tasks

The next step is to find out where tasks occur frequently, as there is no good way to know where tasks occur through Choreographer’s FrameHandler, I have to comment out the code to locate the collapse ToolbarLayout constructor The,

Now, this code registers a windowInset event, which we’ll cover in other articles. Here we’ll focus on how the event is registered. It’s registered using ViewCompat.

ViewCompat obviously made a layer of proxy when it was registered. In this proxy, the logic is that if line 4772 fails, 4789 will be called, and the 4789 code will call requestFitSystemWindows all the way to ViewRootImp

RequestFitSystemWindows calls the scheduleTraversals function,

And will release to the Choreographer task scheduleTraversals function, perform a task is FrameHandler Choreographer, FrameHandler will let ViewRootImp execution performTravers again Als,performTraversals dispatchApplyInsets

“DispatchApplyInsets” will re-dispatch the windowInset event, then execute the windowInset function again in ViewCompat. If line 4772 does not hit the windowInset event, then loop again. If line 4772 does not hit the windowInset event, then loop again Er will always process messages, and after debugging it will always be called in a loop.

To summarise, CollapsingToolbarLayout in the constructor, registered OnApplyWindowInsetsListener events, in registered agent has been passes through a series of calls to the Choreographer FrameHandler happens asynchronously Collapse ToolbarLayout the solution to CollapsingToolbarLayout collapse was to rewrite the collapse ToolbarLayout constructor by loading OnApplyWindo into the view that the mNewActivities in ActivityThread were too busy to handle the logic at the end node WInsetsListener empty, blocking circulation sends the message (I don’t rely on here OnApplyWindowInsetsListener event processing itself and the layout of the child controls, so empty, will not cause other problems).