1. 程式人生 > >android.app.Fragment$InstantiationException異常的解決方案

android.app.Fragment$InstantiationException異常的解決方案

可編譯通過,但是執行的時候就crash。

異常堆疊:

(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: Process: com.android.settings, PID: 3202
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/com.android.settings.SubSettings}: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.test.settings.wifi.tether.WifiTetherUserListSettingsConnected: make sure class name exists, is public, and has an empty constructor that is public
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:193)
(181130_17:03:40.550)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:6669)
(181130_17:03:40.551)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
(181130_17:03:40.607)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.test.settings.wifi.tether.WifiTetherUserListSettingsConnected: make sure class name exists, is public, and has an empty constructor that is public
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.Fragment.instantiate(Fragment.java:538)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at com.android.settings.SettingsActivity.switchToFragment(SettingsActivity.java:589)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at com.android.settings.SettingsActivity.launchSettingFragment(SettingsActivity.java:389)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at com.android.settings.SettingsActivity.onCreate(SettingsActivity.java:293)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7136)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7127)
(181130_17:03:40.617)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	... 11 more
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "com.test.settings.wifi.tether.WifiTetherUserListSettingsConnected" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/data/app/com.android.settings-knknGRqBuThyYHYFLtJtgg==/base.apk"],nativeLibraryDirectories=[/data/app/com.android.settings-knknGRqBuThyYHYFLtJtgg==/lib/arm64, /system/lib64]]
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at dalvk.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	at android.app.Fragment.instantiate(Fragment.java:524)
(181130_17:03:40.618)11-29 15:48:54.149  3202  3202 E AndroidRuntime: 	... 18 more

可以看到,根本原因是fragment中出現的異常:

E AndroidRuntime: Caused by: android.app.Fragment$InstantiationException: Unable to instantiate fragment com.test.settings.wifi.tether.WifiTetherUserListSettingsConnected: make sure class name exists, is public, and has an empty constructor that is public
E AndroidRuntime: 	at android.app.Fragment.instantiate(Fragment.java:538)
E AndroidRuntime: 	at com.android.settings.SettingsActivity.switchToFragment(SettingsActivity.java:589)
E AndroidRuntime: 	at com.android.settings.SettingsActivity.launchSettingFragment(SettingsActivity.java:389)
E AndroidRuntime: 	at com.android.settings.SettingsActivity.onCreate(SettingsActivity.java:293)
E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7136)
E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7127)
E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)

檢視這個異常中涉及到的Fragment:

明明異常中的條件都滿足:public class,has empty constructor that is public。

但是還是報錯了。

根據堆疊資訊其實可以看到是在類載入的時候出現了異常,反射沒有起作用。

根據https://www.tuicool.com/articles/nU7bAz分析的原因:程式碼混淆。

解決方案:修改setting模組下的proguard.flags檔案,引入出現異常的Fragment所在的類包。

如:

 -keep class com.test.settings.wifi.tether.WifiTetherUserListSettingsConnected

本專案中,在原生的setting下進行修改。參考原生的包含方式,修改如下:

然後再編譯執行,就OK了。