android.app.Fragment$InstantiationException異常的解決方案
阿新 • • 發佈:2018-12-28
可編譯通過,但是執行的時候就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了。