Java 如何读取Android崩溃日志?

Java 如何读取Android崩溃日志?,java,android,eclipse,nullpointerexception,crash-dumps,Java,Android,Eclipse,Nullpointerexception,Crash Dumps,几天前,我在谷歌Play商店发布了我的第一个Android应用程序。现在,开发人员控制台中有一个崩溃日志,我正试图找出导致崩溃的原因。虽然我取消了堆栈跟踪的混淆,但我很难理解崩溃日志: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.MyApp/com.example.MyApp.UI.AddressEditor.AddressEditorActivity}: java.lang.Nul

几天前,我在谷歌Play商店发布了我的第一个Android应用程序。现在,开发人员控制台中有一个崩溃日志,我正试图找出导致崩溃的原因。虽然我取消了堆栈跟踪的混淆,但我很难理解崩溃日志:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.MyApp/com.example.MyApp.UI.AddressEditor.AddressEditorActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

Caused by: java.lang.NullPointerException
at com.example.MyApp.UI.AddressEditor.AddressEditorActivity.void setEntryStart(java.util.Date)(Unknown Source)
                                                                    void setCategory(com.example.MyApp.Common.Model.BookingDetail)
                                                                    void loadViewModel(android.os.Bundle)
                                                                    void putAddresDetailUUID(java.lang.String,com.example.MyApp.Common.Model.AddressDetail,android.os.Bundle)
                                                                    void putDate(java.lang.String,java.util.Date,android.os.Bundle)
                                                                    void doSave(com.example.MyApp.UI.AddressEditor.AddressEditorActivity$OnEditorTaskCompleteListener)
                                                                    void saveRecurringTemplate(boolean,boolean,boolean,com.example.MyApp.UI.AddressEditor.AddressEditorActivity$OnEditorTaskCompleteListener)
                                                                    void closeEditor(boolean,boolean,boolean)
                                                                    void access$0(com.example.MyApp.UI.AddressEditor.AddressEditorActivity)
                                                                    void access$5(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,java.lang.String)
                                                                    void access$6(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,android.view.View)
                                                                    void access$7(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,java.util.Date)
                                                                    void access$11(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,com.example.MyApp.Common.Model.Enums.Priorities)
                                                                    void access$13(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,com.example.MyApp.Common.Model.AddressDetail)
                                                                    void access$25(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,double)
                                                                    void access$27(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,boolean)
                                                                    void access$28(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,boolean,boolean,boolean)
                                                                    void access$36(com.example.MyApp.UI.AddressEditor.AddressEditorActivity,boolean,boolean,boolean,com.example.MyApp.UI.AddressEditor.AddressEditorActivity$OnEditorTaskCompleteListener)
at com.example.MyApp.UI.AddressEditor.AddressEditorActivity.void onCreate(android.os.Bundle)(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
... 11 more
显然,崩溃是由NullPointerException引起的,但是如何找到确切的源呢?我必须自顶向下还是自下而上读取堆栈跟踪?到目前为止,我认为跟踪有两个部分:

“dalvik.system.NativeStart.mainNative方法”是堆栈中的第一个元素。 从这里开始,堆栈中的所有其他方法,直到android.app.ActivityThread.performLaunchActivity都被调用。 对吧?

应用程序执行android.app.ActivityThread.performLaunchActivity时,发生NullPointerException。异常的确切位置在日志的第二部分中指定,从底线开始

我自己代码的第一个方法是com.example.MyApp.UI.AddressEditor.AddressEditorActivity.void onCreate,它调用 正当 下面几行我不明白:这里列出的方法,如void setEntryStart或void setCategory,都是AddressEditorActivity的一部分,但不是从onCreate直接调用的

这仅仅是AddressEditorActivity方法的列表,在活动生命周期内的任何时候都使用过,还是这意味着这些方法相互调用?但是setEntryStart不调用setCategory,反之亦然

您必须自上而下或自下而上阅读此方法列表吗?从setEntryStart开始,可以按照列表向下搜索closeEditor开始活动、设置属性和查看模型、编辑数据、保存数据、关闭编辑器,但access$XY条目意味着什么?它们对我来说毫无意义

我是否必须在setEntryStart或access$36中查找NullPointerException的可能原因。。。那会是什么,或者在完全不同的位置

非常感谢你的帮助

编辑: @shayan pourvatan,@Pankaj

这是setEntryStart的代码


NullPointerException的唯一可能性是_entryEnd.before _entryStart,而_entryEnd为null,不是吗?但是如果_entryEnd!=null是在条件失败之前检查的,据我所知,如果条件失败,将取消对if语句的进一步评估。因此,如果_entryEnd为null,则不调用_entryEnd.before\u entryStart,是吗?

这些是堆栈跟踪,方法从堆栈调用,堆栈是后进先出

所以,你必须从上到下阅读

例如:如果您从main调用m1,从m1调用m2,从m2调用m3,堆栈将


main->m1->m2->m3

我想你在com.example.MyApp.UI.AddressEditor.AddressEditorActivity.void setEntryStartjava.util.DateUnknown Source上有问题。是的,你必须查看setEntryStart,可能有一些值被设置为null。@shayan pourvatan,@Pankaj:我已经更新了我的问题,发布了setEntryStart的代码。我看不到Ecxeption应该发生在哪里。如果_entryEnd!=null&&U entryStart!=null{if_entryEnd.before_entryStart _entryEnd=_entryStart;}我理解你的意思,但我找到的所有来源都说Java在if语句中对&&和|使用短路求值。因此,只有当_entryEnd和_entryStart都不为null时,才会计算_entryEnd.before。那么使用两个if子句会有什么区别呢?谢谢!当然,我知道堆栈是后进先出的,但正如这里所描述的,当我从上到下阅读它时,堆栈跟踪没有意义。首先,似乎有两个部分必须分开阅读。其次,第二部分中的方法不相互调用。读取setCategory->setEntryStart没有意义,因为setCategory不调用setEntryStart。。。
private Date _entryStart;
private void setEntryStart(Date start) {
    _entryStart = start;
    if (_entryEnd != null && _entryStart != null && _entryEnd.before(_entryStart))
        _entryEnd = _entryStart;
}

private Date _entryEnd;
private void setEntryEnd(Date end) {
    _entryEnd = end;
    if (_entryEnd != null && _entryStart != null && _entryEnd.before(_entryStart))
        _recurringStart = _entryEnd;
}