【问题标题】:App crashes during initialization because of opened dialog由于打开的对话框,应用程序在初始化期间崩溃
【发布时间】:2023-03-18 05:54:01
【问题描述】:

这个崩溃已经在我的开发者控制台中出现了很长时间,我无法以任何方式重现它。

我有一个以 MainActivity 开头的应用。在 onCreate 中,一些数据是从后端异步下载的。在此活动中按下按钮时,会打开一个对话框,其中显示一些从服务器下载的数据。

这是崩溃:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.******.******/com.******.******.MainActivity}: com.******.******.users.UserData$DataNotFoundException: Requested element not found
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6942)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

Caused by com.******.******.users.UserData$DataNotFoundException: Requested element not found
       at com.******.******.users.UserData.getData(UserData.java:478)
       at com.******.******.UserDialog.onCreateDialog(UserDialog.java:87)
       at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:380)
       at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1412)
       at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
       at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
       at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
       at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
       at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
       at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
       at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
       at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1341)
       at android.app.Activity.performStart(Activity.java:7200)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2920)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6942)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

让我感到困惑的是,由于对话框膨胀时发生崩溃,因此在 performLaunchActivity 中发生了崩溃。但是,该对话框不是在 Activity 的 onCreate 中创建的,而是在用户按下按钮后创建的。然而,该按钮没有被点击(我在点击监听器中添加了一个日志,它从未被调用)。

我在 GitHub 问题跟踪器中看到了类似模式的崩溃,但没有回复,所以这似乎是一种常见的模式,但很难调试。

问题是在什么情况下可以从 performLaunchActivity 实例化 Dialog,即使 onCreate() 方法中没有对对话框的引用。我猜它与活动的生命周期有关,但我无法破解它。

【问题讨论】:

  • 请分享您的代码。如果有任何帮助,请检查this
  • 我无法分享我的所有代码。我认为帖子中有足够的信息。
  • 我知道规则。我不是想找人调试我的代码,问题是在什么情况下,活动在启动时可能会因为不应打开的对话框而崩溃。
  • @ig343 可以分享 UserData java 文件吗
  • @ig343 你是否在 onResume 或 onStart 方法中定义了对话框?

标签: android android-layout android-activity android-lifecycle android-dialog


【解决方案1】:

您的崩溃可能发生在屏幕旋转时,或者在后台进程死亡后恢复应用程序。在这种情况下,DialogFragment 是在没有用户交互的情况下创建的。您是否检查并推理了这些情况?

您可能希望在按照documentation 打开对话框时将数据作为参数传递。这样,系统将在数据完整的情况下重新创建对话框。

【讨论】:

  • 感谢史蒂夫的回答。我检查屏幕旋转,但无法重现。还尝试启用开发人员选项,该选项会在活动不再可见但也无法重现时终止活动。 crashlytics 日志显示,崩溃发生时 RAM 使用率不一定很高。您还有其他想法可以尝试吗?
  • @ig343 不保留活动不是进程死亡。打开对话框后,点击主页按钮将应用程序置于后台。然后发出adb shell am kill com.xyz.yourapp。然后重新进入应用程序。
【解决方案2】:

如果 Android 需要在显示对话框时重新创建 Activity,它会在重新创建 Activity 时重新创建对话框。例如,当您的 Activity 在后台为前台应用程序释放内存时,它可能会被终止。

在这种情况下,如果您的对话框使用在 Activity 被终止之前存在的内存中的数据,但这些数据不会再次通过对话框实例化,则您的对话框可能会遇到问题。

因此,对话框具有参数,这些参数会在重新创建时保留并传递给对话框。 使用 setArguments(Bundle args) 将数据传递给对话框。

【讨论】:

    【解决方案3】:

    根据您的堆栈跟踪,我的猜测是您有函数或使用了某种全局变量,当您异步获取数据时它会发生变化,然后它会崩溃,因为您的 dialog 尚未膨胀。

    我最好的猜测是您使用了DialogFragment,它的生命周期与常规片段有点不同,它正在尝试准备布局中的数据。

    我只是在这里猜测,因为您的问题还不够清楚,但要调试和修复此问题,我建议您更改 getData 方法并在其中放入常量数据以查看崩溃是否仍然发生,如果崩溃停止它是因为您使用的变量,应该处理您的片段和对话框生命周期以修复崩溃,如果崩溃仍然会发生,请更改为常规片段并发布发生的情况,以便我知道发生了什么。

    总体而言,当您使用某些变量或使用尚未生成的数据填充某些视图时会发生这种情况,如果您尝试更改已在主程序中使用的视图或变量,也可能是由该异步方法引起的线程。

    让我知道并希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      这就是为什么大多数应用程序在异步获取数据时都有加载屏幕的原因。 可能是您的代码没有任何问题,但用户能够在获取数据之前以某种方式点击按钮。 您可以尝试在低性能手机的模拟器上部署该应用程序。 检查发生崩溃的手机型号

      【讨论】:

        【解决方案5】:

        @ig343

        看来你的问题是因为

        Caused by com.******.******.users.UserData$DataNotFoundException: Requested element not found
           at com.******.******.users.UserData.getData(UserData.java:478)
        

        选项 1: 对行 (UserData.java:478) 使用异常处理程序 {try catch to handle DataNotFoundException} 并记录错误。

        选项 2: 尝试将所有请求的元素值设为 null。

        玩得开心....

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-06
          • 1970-01-01
          相关资源
          最近更新 更多