“This is the 16th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

After adjusting the font size of the system, I switched the APP from the background to the foreground and found that the APP crashed.

The official documentation about this problem: developer. The android. Google. Cn/guide/topic…

First, the cause of the problem

After consulting some materials, I found that the unit of text annotation in APP is SP. When the sp metric changes when the system font size changes, the system will send a notification to the APP, telling it that the configuration has changed and the interface needs to be refreshed again. A similar operation is done in the onConfigurationChanged() method, just like the horizontal and vertical screen switches.

To switch between vertical and horizontal screens, the app goes through the lifecycle methods onDestroy() and onCreate(). Our app is usually configured to have a fixed orientation so that it doesn’t switch between horizontal and vertical screens. The configChanges property prevents the interface from being destroyed and rebuilt.

android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|keyboardHidden
Copy the code

Back to the problem itself, here’s how it happened: The system font size changed and it sent a notification to the app when it returned to the foreground. The way the app is going through its life cycle at this point is

onDestroy()
onCreate()
onResume()
Copy the code

This section describes how to refresh the UI.

Here’s the thing: the app is acting as an exception to the onDestroy() method, rather than the normal onDestroy() exit by pressing the return key. The onSaveInstanceState() method will temporarily save the previous interface state or variable information. It’s easy to use onCreate() directly from the bundle. However, it is an abnormal state after all. When the information of some entities or the state of the fragment stack is recovered, it may be confused, resulting in error display or crash.

Second, solutions

android:configChanges="orientation|screenSize|keyboardHidden|**fontScale**
Copy the code
  • Add fontScale property to avoid system font changes and re-create the interface. If only this is done, the font size of the app will change with the font size of the system when switching from background to foreground.
  • Change the font unit in APP from SP to DP, so that the font display of APP will not change with the font change of the system.

It can be configured according to product requirements.

Other issues

After solving the above problem, some students who are good at thinking asked, this is to solve the problem caused by switching the font size of the system. What if I switch the font style of the system? How to solve the problem?

In fact, with the above foundation, it is much easier to solve this problem.

When we switch font sizes, we know that the system will send a notification, so we just set the fontScale property. However, there was no notice from the system to switch font styles, nor did Google. There were also various questions on the stack, and no monitoring events or methods were found.

After switching styles, we can look at the Activity lifecycle, again onDestroy(),onCreate()… Because of the destroy exception, the system saves the current state information to the saveInstanceState() bundle, which onCreate() removes from the bundle to restore it. Sometimes, the saved bundle is in the wrong state, causing the interface to load incorrectly.

OnCreate () : check if there is any data in the bundle. If there is any data in the bundle, empty it, and then go through the normal process. The specific code is as follows:

@Override protected void onCreate(Bundle savedInstanceState) { **if (null ! = savedInstanceState) savedInstanceState = null; ** super.onCreate(savedInstanceState); }Copy the code

This configuration can be placed in the BaseActivity of your project to reduce changes to existing code.

Think about it: in fact, at this point, you will find that you can also change the font size in this way, and even after this configuration, forget about fontScale and let the interface refresh itself, the second onCreate() will have the same effect as re-entering the app.