用于 onCreate 的 java.lang.NoSuchMethodException

cla*_*vio 20 java android android-fragments kotlin

我在 Google Play 崩溃日志中看到崩溃,这真的让我很难过。

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3086)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3229)
  at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:78)
  at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:108)
  at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:68)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1926)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:214)
  at android.app.ActivityThread.main (ActivityThread.java:6981)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1445)
Caused by: androidx.fragment.app.Fragment$InstantiationException: 
  at androidx.fragment.app.Fragment.instantiate (Fragment.java:462)
  at androidx.fragment.app.FragmentContainer.instantiate (FragmentContainer.java:50)
  at androidx.fragment.app.FragmentState.instantiate (FragmentState.java:80)
  at androidx.fragment.app.FragmentManagerImpl.restoreAllState (FragmentManager.java:3109)
  at androidx.fragment.app.FragmentController.restoreAllState (FragmentController.java:158)
  at androidx.fragment.app.FragmentActivity.onCreate (FragmentActivity.java:344)
  at androidx.appcompat.app.AppCompatActivity.onCreate (AppCompatActivity.java:85)
  at com.autotask.jbarra.kotlinmvvm.MainActivity.onCreate (MainActivity.kt:102)
  at android.app.Activity.performCreate (Activity.java:7326)
  at android.app.Activity.performCreate (Activity.java:7317)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1271)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3066)

Caused by: java.lang.NoSuchMethodException: 
  at java.lang.Class.getConstructor0 (Class.java:2328)
  at java.lang.Class.getConstructor (Class.java:1725)
  at androidx.fragment.app.Fragment.instantiate (Fragment.java:443)
Run Code Online (Sandbox Code Playgroud)

问题是,主要活动的第 102 行没什么特别的

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState) //This is line 102
Run Code Online (Sandbox Code Playgroud)

什么可能导致这种情况?为什么 oncreate 没有抛出这样的方法?它发生在一些用户的设备上,我无法重现它。

laa*_*lto 10

活动正在从实例状态包中恢复。还原操作的一部分是重新创建其片段。

您的活动有一个片段,片段类没有框架所需的 0-arg 构造函数。

  • “不保留活动”开发人员设置强制活动在转到另一个活动时保存状态,在返回时触发恢复。 (4认同)
  • 没有人有完整的解释以及如何解决它?我有 0 arg 构造函数,但仍然收到此错误... (4认同)
  • @ch3tanz 删除显式构造函数或添加 0-arg 构造函数。 (3认同)
  • @laalto 如何解决这个问题? (2认同)

use*_*392 9

我有同样的问题。其他答案没有帮助。

对我来说,它看起来像是 Proguard。这解释了为什么它只发生在生产/发布版本中,以及为什么我在调试时无法重现它。

如果您遇到 OP 的问题,请尝试以下操作:

  1. 构建混淆的 .apk。我使用了已签名的版本,并将其发布到应用程序商店......
  2. 在设备的开发者选项中启用“不保留活动”。
  3. 在您的设备中安装 .apk,然后打开崩溃并包含 Fragment 的 Activity。
  4. 离开您的应用程序(最小化/主页按钮/...)并从最近的应用程序菜单中重新打开它。

它会崩溃吗?然后尝试使用未混淆的调试版本。如果没有,那么它可能是 Proguard。

为了修复它,我执行了以下操作:

  1. 在应用程序模块的根文件夹中创建一个 proguard-rules.pro 文件。
  2. 将 -keep class * extends androidx.fragment.app.Fragment{} 添加到该文件。
  3. 然后,在应用程序的 build.gradle 中,

添加:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅 Yaroslav Mytkalyk 的答案:Fragment Instantiation crash,它帮助我解决了这个问题,尽管它现在有点旧且过时(例如“runProguard true”已过时)。

至少现在当我执行上述步骤时它不会崩溃。

PS:正如其他答案中提到的,我这样做的同时将 0-arg 构造函数添加到我的片段中,因为这是我的第一次修复尝试。我相信 Proguard 本身就是问题所在,并且没有必要添加所述构造函数,但我现在无法测试该假设。

  • 有了这个规则,你的所有片段都不会被缩小,这不是一个好的做法 (2认同)