Solution to fragment management and overlap problem in Android

1、 Fragment introduction

Since the introduction of fragment in 3.0, more and more fragments have been used in projects. In particular, the main interface is the tab page at the bottom. Click to change the content. Of course, fragments exist widely in projects. For example, in the design of the home page, each navigation at the bottom usually corresponds to this corresponding fragment. Using fragments reduces the responsibility of the corresponding activity, Let fragmen t act as part of the activity's responsibilities. Moreover, when using fragment, it improves the encapsulation and reuse of code and layout, which is particularly obvious.

Fragment has its own lifecycle management, but it depends on the corresponding activity.

Well, the introduction of life cycle is not the focus of this article. Post a picture to deepen your impression.

2、 Stack management and life cycle of fragment

addToShow

If add () and hide () are used to control the jump, the corresponding life cycle is as follows:

If you return from the second fragment to the first fragment again:

It can correspond to the above picture. When returned, the current fragment is directly destroyed, and then the first fragment only changes from an invisible state to a visible state without going through the relevant life cycle. Therefore, the hide () method will not trigger onpause () and other life cycle callback methods.

Then, if we lock the screen or switch back after switching tasks:

It can be seen here that all fragments go back and call back the relevant methods with the activity, whether it is visible or not.

replaceTo

The method of replace () is actually equivalent to remove () removing all fragments previously added to the container, and then add () adding the current. Since the remove () method will be called, the life cycle is like this:

Compared with the above logs, after the remove() call, the fragment will execute onpause(), onstop(), ondestroyview() will be called once, but ondestroy(), ondetach() will not be called, which means that its view will be destroyed, so when it comes back, it must be recreated:

Similarly, if you lock the screen or switch back after switching tasks:

You can see that when replace () is used, only the top fragment will respond to the corresponding life cycle. In the add () above, both fragments go through the related life cycle.

So the question comes: when do you use replace() and when do you use add() and hide()?! In fact, in comparison, it is mainly the problem of efficiency and related life cycle.

Efficiency issues:

If you use replace (), you need to go oncreateview () to refill the layout every time. If the oncreateview () method also contains initialization data, it also means that the related must be executed again.

Data and page refresh problems:

If you use replace() to jump from afragment to bfragment, and the relevant data updated in bfragment will affect the relevant view display of afragment, there will be problems here. Even if you use eventbus notification, afragment can indeed be changed, but when you switch back to afragment, it will go to oncreateview() to re create the relevant layout, Unless you save it to the global and set it again during initialization, the previously sent data will be lost.

Life cycle matching problem:

Life cycle methods are matched in pairs. In the replace () method mentioned above, a takes the following three life cycle callback methods when replacing:

When fallback to it, the corresponding three life cycle callbacks are called:

However, it will be awkward to use add () and hide (). You will find that its onpause () and onresume () methods do not match at all. As long as add (), even if you call hide (), its life cycle callback will not be affected, and there will be no callback such as onpause (). This means that when we lock the screen or switch tasks back, all fragments from add will execute the relevant life cycle callback methods:

So if you do statistics, there may be a little problem here. Of course, whether it is displayed or not is not completely unknown.

In the fragment, you can use the method of ishide () or the method of onhiddenchanged (Boolean hide) to obtain whether the current state is hide.

To sum up, we use add() and hide(). We need to pay attention to the mismatch of callback methods such as onresume() and the time to obtain data. We should request relevant data when it is visible (when ishidden() returns false).

When you use replace (), you should pay attention to frequent layout filling and data transfer between fragments.

State save

Fragment overlap exception

Must have encountered the problem of fragment overlapping display!?

This is mainly the problem that the activity helps us to restore the state. The background process will not be left open in the setting to facilitate the corresponding situation:

Then, on the second page, go back to the home page and enter again. Let's take a look at an abnormal log:

Nima, did you find the problem? Our fragment9 was created twice. One is the same as before, invisible, and the other is actually visible, and is still on the top. Therefore, this causes the overlap of fragments.

Another situation is that the breakpoint finds that a fragment is initialized successfully and the layout is available, but the views in it are all empty. I have also encountered this situation.

Why is this problem? Because in this abnormal case, the temporary data saving mechanism of Android will be triggered, and fragment is the key object it temporarily saves. So the previous two fragment related states have been saved! But in oncreate() of activity, I wrote this:

That is to say, no matter whether there is a saved state or not, I will create and load fragment9 again, so this causes fragment9 to be created twice (one is recovered by the system, and the relevant state is also normal, and the other is created in oncreate()). Then, to avoid this problem, we need to find a way on savedinstancestate. Now that it has saved the relevant fragments, we don't have to create them again!

Therefore, savedinstancestate cannot be ignored. However, if you think it's over here, you underestimate the hole of fragment. If your support library is lower than 24, even if you judge to create savedinstancestate, there may be overlap!

Here we will talk about the class fragmentstate, which is used to save the related states of fragments.

Did you find anything?? The mhidden state was not saved in the previous fragmentstate!

In addition, relevant issue submissions were also searched, but the relevant bug fixes mentioned were not found in Android's revision history. Therefore, when the mhidden field is officially added has not been verified.

After talking so much, I finally talked about the solution. In fact, the principle is very simple. Since it is not automatically saved, we will manually save the mhidden state when saving the state, and manually display or hide it according to the saved mhidden state during initialization.

Finally, a simple tool class and basefragment are encapsulated to handle fragment related transactions.

summary

The above is the whole content of this article. I hope the content of this article can be helpful to Android developers. If you have any questions, you can leave a message.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>