Regarding the problem of restarting the Android application after inserting some wireless mice
foreword
In the Android 9.0 project, the test engineer plugged in some USB wireless mice when verifying the problem, which would cause the current APK to be destroyed and then restarted to go through the life cycle again.
Why does the Activity restart?
Why does it restart?
We know with a high probability that there are generally the following reasons for app restarts:
- The APP is abnormal (WeChat has such a problem, flash back and restart)
The machine state has changed (such as changing the language), causing the Activity to restart
However, since there is no exception log in the log, the latter case is considered.
The following is in "Insert a wireless mouse Android application restart problem"
Later, it was found that plugging in a problematic USB wireless transceiver would generate 2 devices, a mouse and a keyboard. That's right, this is a wireless transceiver integrated with a keyboard and mouse set. It is this keyboard that causes the current phenomenon, and some wireless mice have wireless transceivers that are not a keyboard and mouse set, so there will only be one mouse device, so plug in There is no problem going up.
This is more affirmative of my guess [the machine state has changed (such as changing the voice), causing the Activity to restart].
I deliberately printed the log of the Activity's life cycle and found that the Activity was destroyed and then restarted.
The Android documentation has the following instructions ( also explained in the previous " Introduction to configChanges configuration of AndroidManifest.xml ")
If the android: configChanges in the Activity in our AndroidManifest.xml declares the corresponding attribute, the Activity will not restart and call onConfigurationChanged() when the attribute changes
Therefore, to solve this problem, we can declare the state value that will change after inserting the USB wireless mouse in AndroidManifest.xml.
However, we don't know which value was changed. In order to verify, we can do an experiment in the following way, and then find out the murderer behind the scenes.
find the murderer
Sharpen the knife and scream at the pigs and sheep.
Step 1: configChanges declaration of MainActivity in AndroidManifest.xml to add the state that may change
android:configChanges="orientation|uiMode|keyboard|keyboardHidden|fontScale|touchscreen|navigation|screenLayout|colorMode"
Step 2: implement onConfigurationChanged in MainActivity, and add the following print.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged keyboard : " + newConfig.keyboard);
Log.d(TAG, "onConfigurationChanged densityDpi : " + newConfig.densityDpi);
Log.d(TAG, "onConfigurationChanged fontScale : " + newConfig.fontScale);
Log.d(TAG, "onConfigurationChanged hardKeyboardHidden : " + newConfig.hardKeyboardHidden);
Log.d(TAG, "onConfigurationChanged keyboardHidden : " + newConfig.keyboardHidden);
Log.d(TAG, "onConfigurationChanged mcc : " + newConfig.mcc);
Log.d(TAG, "onConfigurationChanged mnc : " + newConfig.mnc);
Log.d(TAG, "onConfigurationChanged navigation : " + newConfig.navigation);
Log.d(TAG, "onConfigurationChanged navigationHidden : " + newConfig.navigationHidden);
Log.d(TAG, "onConfigurationChanged orientation : " + newConfig.orientation);
Log.d(TAG, "onConfigurationChanged screenHeightDp : " + newConfig.screenHeightDp);
Log.d(TAG, "onConfigurationChanged screenLayout : " + newConfig.screenLayout);
Log.d(TAG, "onConfigurationChanged smallestScreenWidthDp : " + newConfig.smallestScreenWidthDp);
Log.d(TAG, "onConfigurationChanged touchscreen : " + newConfig.touchscreen);
Log.d(TAG, "onConfigurationChanged uiMode : " + newConfig.uiMode);
Log.d(TAG, "onConfigurationChanged locale : " + newConfig.locale)
Step 3: Plug and unplug the USB wireless transceiver
The following is the log print of plugging and unplugging.
# 插入
onConfigurationChanged keyboard : 2
onConfigurationChanged densityDpi : 160
onConfigurationChanged fontScale : 1.0
onConfigurationChanged hardKeyboardHidden : 1
onConfigurationChanged keyboardHidden : 1
onConfigurationChanged mcc : 460
onConfigurationChanged mnc : 7
onConfigurationChanged navigation : 2
onConfigurationChanged navigationHidden : 1
onConfigurationChanged orientation : 2
onConfigurationChanged screenHeightDp : 670
onConfigurationChanged screenLayout : 268435812
onConfigurationChanged smallestScreenWidthDp : 720
onConfigurationChanged touchscreen : 3
onConfigurationChanged uiMode : 17
onConfigurationChanged locale : zh_CN
# 拔出
onConfigurationChanged keyboard : 1
onConfigurationChanged densityDpi : 160
onConfigurationChanged fontScale : 1.0
onConfigurationChanged hardKeyboardHidden : 2
onConfigurationChanged keyboardHidden : 1
onConfigurationChanged mcc : 460
onConfigurationChanged mnc : 7
onConfigurationChanged navigation : 1
onConfigurationChanged navigationHidden : 2
onConfigurationChanged orientation : 2
onConfigurationChanged screenHeightDp : 670
onConfigurationChanged screenLayout : 268435812
onConfigurationChanged smallestScreenWidthDp : 720
onConfigurationChanged touchscreen : 3
onConfigurationChanged uiMode : 17
onConfigurationChanged locale : zh_CN
The status of navigation, navigationHidden, keyboard, and hardKeyboardHidden in the log has changed.
solution
From the above log, we know that the states of navigation, navigationHidden, keyboard, and hardKeyboardHidden have changed, and we have not configured the monitoring of these states, so the Activity is restarted once.
Therefore, our Activity configuration in AndroidManifest.xml is as follows:
android:configChanges="keyboard|navigation|keyboardHidden"