Android: 如何找到导致此崩溃的我自己的代码行?

Android: How can I find the line of MY OWN code which causes this crash?

我从崩溃中得到以下堆栈跟踪:

java.lang.IndexOutOfBoundsException: Invalid index 6, size is 2
   at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
   at java.util.Arrays$ArrayList.get(Arrays.java:66)
   at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
   at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:390)
   at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
   at android.widget.Spinner.makeAndAddView(Spinner.java:546)
   at android.widget.Spinner.layout(Spinner.java:495)
   at android.widget.Spinner.onLayout(Spinner.java:459)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
   at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1652)
   at android.widget.TableRow.onLayout(TableRow.java:123)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
   at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
   at android.widget.TableLayout.onLayout(TableLayout.java:448)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
   at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
   at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
   at android.widget.ScrollView.onLayout(ScrollView.java:1459)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:907)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663)
   at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521)
   at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
   at android.view.View.layout(View.java:14008)
   at android.view.ViewGroup.layout(ViewGroup.java:4373)
   at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
   at android.view.Choreographer.doCallbacks(Choreographer.java:562)
   at android.view.Choreographer.doFrame(Choreographer.java:532)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
   at android.os.Handler.handleCallback(Handler.java:725)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:5041)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
   at dalvik.system.NativeStart.main(NativeStart.java)

如何找出我自己的代码中的哪一行导致了这次崩溃?

有些崩溃会在堆栈跟踪中显示您的代码。其他人不会。一种常见的 "will not" 情况是这样的情况,崩溃是由您所做的事情触发的,但工作稍后在主应用程序线程上进行。

在这种情况下,Spinner(显然)不会立即验证选择索引,因此您设置它的调用没有失败。但是,设置选择会向主应用程序线程的工作队列添加一个作业以重新呈现此小部件。当那个发生时,选择索引无效,你崩溃了。

在理想情况下,预先会有更多的验证,所以您会在 setter 上失败并更直接地看到问题的根源。有时确实会发生这种情况。但有时它不会,你会留下像你一样的堆栈跟踪。虽然您不能直接指向代码中的一行并说 "Eureka! That's where my problem comes from!",但您至少知道出了什么问题的基础知识,并且您需要仔细检查您最近所做的影响崩溃小部件的更改。