注:我知道這個問題是重複的,你很可能鼓勵downvote,但,如果檢查爲null,怎麼會有NullPointerException?
- 這事發生在Android框架代碼
- 它發生,即使有一個空檢查,沒有多線程。
我最近部署了我的APK在Play商店中,並收到NullPointerException
了極少數用戶(4):
Exception java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Object.equals(java.lang.Object)' on a null object reference
android.widget.AdapterView.getPositionForView (AdapterView.java:607)
com.snap.testsnapboard.AlbumSelectActivity$1.onItemClick (AlbumSelectActivity.java:114)
android.widget.AdapterView.performItemClick (AdapterView.java:305)
android.widget.AbsListView.performItemClick (AbsListView.java:1146)
android.widget.AbsListView$PerformClick.run (AbsListView.java:3057)
android.widget.AbsListView.onTouchUp (AbsListView.java:3876)
android.widget.AbsListView.onTouchEvent (AbsListView.java:3641)
android.view.View.dispatchTouchEvent (View.java:8481)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2400)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2093)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2406)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2107)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2406)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2107)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2406)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2107)
android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2406)
android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2107)
com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent (PhoneWindow.java:2369)
com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent (PhoneWindow.java:1719)
android.app.Activity.dispatchTouchEvent (Activity.java:2785)
com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent (PhoneWindow.java:2330)
android.view.View.dispatchPointerEvent (View.java:8676)
android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:4141)
android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:4007)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:3562)
android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:3615)
android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:3581)
android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:3698)
android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:3589)
android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:3755)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:3562)
android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:3615)
android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:3581)
android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:3589)
android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:3562)
android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:5825)
android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:5799)
android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:5770)
android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:5915)
android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:185)
android.os.MessageQueue.nativePollOnce (MessageQueue.java)
android.os.MessageQueue.next (MessageQueue.java:143)
android.os.Looper.loop (Looper.java:122)
android.app.ActivityThread.main (ActivityThread.java:5254)
java.lang.reflect.Method.invoke (Method.java)
java.lang.reflect.Method.invoke (Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:902)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:697)
這個例外在該行while ((v = (View) listItem.getParent()) != null && !v.equals(this)) {
起源於AdapterView.java
:
/**
* Returns the position within the adapter's data set for the view, where
* view is a an adapter item or a descendant of an adapter item.
* <p>
* <strong>Note:</strong> The result of this method only reflects the
* position of the data bound to <var>view</var> during the most recent
* layout pass. If the adapter's data set has changed without a subsequent
* layout pass, the position returned by this method may not match the
* current position of the data within the adapter.
*
* @param view an adapter item, or a descendant of an adapter item. This
* must be visible in this AdapterView at the time of the call.
* @return the position within the adapter's data set of the view, or
* {@link #INVALID_POSITION} if the view does not correspond to a
* list item (or it is not currently visible)
*/
public int getPositionForView(View view) {
View listItem = view;
try {
View v;
while ((v = (View) listItem.getParent()) != null && !v.equals(this)) {
listItem = v;
}
} catch (ClassCastException e) {
// We made it up to the window without find this list view
return INVALID_POSITION;
}
if (listItem != null) {
// Search the children for the list item
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
if (getChildAt(i).equals(listItem)) {
return mFirstPosition + i;
}
}
}
// Child not found!
return INVALID_POSITION;
}
分其他的事情值得一提:
- 我有一個連有一個頁腳視圖通過
addFooterView()
- 我要檢查,如果這頁腳視圖被點擊,什麼也不做,因爲這種觀點只是包含了一些列表視圖圖形不是通常的列表項目。
對於這一點,我寫了下面的代碼:
// Since we have a Footer view attached to the ListView, the position selected // might not always map 1-to-1 with the ArrayList we are using to represent the // Album model objects list. Lets check if the Footer view has been selected and // in this case, do nothing. if(myListView.getPositionForView(loadMoreView) == arg2){ // Blank return return; }
這是最終調用AdapterView.java
裏面的方法的代碼。現在,爲什麼在while循環中有空檢查並且所有UI處理僅在主線程中發生時會有NullPointerException
?
這是一個被重複關閉的高風險 - 空指針異常很快就會關閉 - 您可能想要添加這個問題中不同的問題,這些問題無法在upvoted Qs中得到解答,在這裏討論相同的問題 –
@YvetteColomb:NullPointerException通用性足以被重複關閉。我希望在框架代碼中放棄一些光線,因爲畢竟有空檢查 –
您如何確定異常的行? – Bob