我正在尝试调试我的Android应用程序的神秘崩溃,这种崩溃似乎发生在低内存条件下。相关应用的来源可从https://bitbucket.org/stativ/chmupocasi获得。应用程序包是cz.jirkovsky.lukas.chmupocasi
当手机开始内存不足时我会尝试从最近的应用列表(长按 Home 按钮后显示的应用程序)重新打开应用程序,应用程序崩溃。
我尝试使用Android Studio调试应用程序,但是在点击主Activity的onCreate()和onStart()中的任何断点之前应用程序总是崩溃,这使得无法调试。更糟糕的是,即使logcat不包含任何信息,应用程序崩溃时显示的唯一相关行是:
I/ActivityManager( 428): Displayed cz.jirkovsky.lukas.chmupocasi/.MainActivity: +1s45ms (total +23m23s835ms)
如果我遗漏了某些内容,可以在http://pastebin.com/TtSuqxCW获得完整的logcat。
最后,我已经尝试将调试器附加到应用程序崩溃后,当Android的对话框“不幸的是应用程序已经停止”时显示。我没有看到任何代码在任何线程中运行。以下是“导出线程”包含的内容:
<1> main@830017304224, prio=5, in group 'main', status: 'RUNNING'
at android.os.BinderProxy.transact(Binder.java:-1)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:3147)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:76)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
at dalvik.system.NativeStart.main(NativeStart.java:-1)
<10> Binder_2@830026133152, prio=5, in group 'main', status: 'RUNNING'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<9> Binder_1@830026131496, prio=5, in group 'main', status: 'RUNNING'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<8> FinalizerWatchdogDaemon@830026116408 daemon, prio=5, in group 'system', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:364)
at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:214)
at java.lang.Thread.run(Thread.java:856)
<7> FinalizerDaemon@830026115976 daemon, prio=5, in group 'system', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:401)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:102)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:73)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:169)
at java.lang.Thread.run(Thread.java:856)
<6> ReferenceQueueDaemon@830026115560 daemon, prio=5, in group 'system', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:364)
at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:129)
at java.lang.Thread.run(Thread.java:856)
<5> Compiler@830026115320 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<3> Signal Catcher@830026114840 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
<2> GC@830026114616 daemon, prio=5, in group 'system', status: 'WAIT'
at dalvik.system.NativeStart.run(NativeStart.java:-1)
如果我尝试检查主线程,我可以看到ThreadGroup中某处存在未处理的异常:
No such instance field: 'nthreads'
如何调试此类崩溃或如何获取有关它的更多信息?
答案 0 :(得分:1)
我终于找到了解决方案。这实际上是两个不同的问题。
第一个是我的设备(华为Y300)没有记录任何可以使用logcat检索的堆栈跟踪。这很可能是通过我今天早些时候进行的重新启动解决的,或者不太可能是因为我尝试通过android.util.Log
使用日志记录来记录一些调试信息。
第二个是崩溃本身。从崩溃中获得堆栈跟踪后,问题很容易解决。尽管我使用调试器获得的先前信息指出了线程的一些问题,但真正的原因是以下异常:
android.app.Fragment$InstantiationException: Unable to instantiate fragment cz.jirkovsky.lukas.chmupocasi.RetainFragment: make sure class name exists, is public, and has an empty constructor that is public
真正的原因是RetainFragment
是包私有的。但是,从Fragment
继承的所有类必须是公共类或公共静态内部类。
如果不是,那可能会让你感到非常伤心。原因是,即使它在包是私有的时候似乎工作正常,但是在它被销毁之后重新创建Fragment
以在低mem条件下回收某些内存时它将失败。
最后的道德是你不应该总是听你的IDE说什么,因为我在Android Studio告诉我这个片段类可以被包装为私有之后引入了这个bug。