IllegalStateException 예외 해결 프로세스 기록

6536 단어
예외 내용:
07-16 20:21:37.411: ERROR/AndroidRuntime(324): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(-1, class com.ringcentral.android.utils.ui.widget.PullToRefresh$7) with Adapter(class android.widget.HeaderViewListAdapter)]
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.widget.ListView.layoutChildren(ListView.java:1492)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.widget.AbsListView.onTouchModeChanged(AbsListView.java:1960)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver.java:591)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.view.ViewRoot.ensureTouchModeLocally(ViewRoot.java:2021)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.view.ViewRoot.ensureTouchMode(ViewRoot.java:2005)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1774)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.os.Looper.loop(Looper.java:123)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at android.app.ActivityThread.main(ActivityThread.java:4627)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at java.lang.reflect.Method.invokeNative(Native Method)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at java.lang.reflect.Method.invoke(Method.java:521)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-16 20:21:37.411: ERROR/AndroidRuntime(324):     at dalvik.system.NativeStart.main(Native Method)

이상하면 틀린 컨트롤을 보고하는 탓입니다. 제 인터페이스는 전혀 쓸모가 없습니다. 오류가 발생하는 시기는 제 만남에서 초점을 전환하기 때문입니다~!(아날로그기에서 위아래 좌우 키를 누르면 잘못 보고합니다.)...어이가 없네.원본 코드를 보고 싶지 않아 한바탕 꼬였다.인터페이스의 관련 컨트롤에서 setFocusable () 을 임의로 설정합니다.하루를 보냈지만 아무런 진전이 없다.아, 그냥 억지로 원본을 보는 게 낫겠다.
예외 스택 정보에 따라 오류가 ListView에 보고되었습니다.layoutChildren()에 있는.
            if (mItemCount == 0) {
                resetList();
                invokeOnItemScrollListener();
                return;
            } else if (mItemCount != mAdapter.getCount()) {
                throw new IllegalStateException("The content of the adapter has changed but "
                        + "ListView did not receive a notification. Make sure the content of "
                        + "your adapter is not modified from a background thread, but only "
                        + "from the UI thread. [in ListView(" + getId() + ", " + getClass() 
                        + ") with Adapter(" + mAdapter.getClass() + ")]");
            }

mItemCount는 ListView 목록 항목의 개수입니다.어댑터가 제공하는count와 일치하지 않기 때문에 오류를 보고했습니다.
잘못 보고된 정보는 틀림없다. 우리 공사에서 새로 고친 컨트롤러에 문제가 있다.문제가 보편성을 가지지 않기 때문이다.나는 이번 연구 원본에서 얻은 수확을 다시 한 번 이야기할 것이다.
ListView:
    public void setAdapter(ListAdapter adapter) {
        if (mAdapter != null && mDataSetObserver != null) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
        }

        resetList();
        mRecycler.clear();

        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }

        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;

        // AbsListView#setAdapter will update choice mode states.
        super.setAdapter(adapter);

        if (mAdapter != null) {
            mAreAllItemsSelectable = mAdapter.areAllItemsEnabled();
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
            checkFocus();

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());

            int position;
            if (mStackFromBottom) {
                position = lookForSelectablePosition(mItemCount - 1, false);
            } else {
                position = lookForSelectablePosition(0, true);
            }
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);

            if (mItemCount == 0) {
                // Nothing selected
                checkSelectionChanged();
            }
        } else {
            mAreAllItemsSelectable = true;
            checkFocus();
            // Nothing selected
            checkSelectionChanged();
        }

        requestLayout();
    }
ListView는 addHeader를 먼저 설정하고 Adapter를 설정해야 하기 때문에 setAdapter를 먼저 추가하지 못합니다.아래 몇 줄의 코드 때문에
   if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }

원래 ListView에 헤더가 있을 때, HeaderView ListAdapter의 실례를 만들고 당신의 adapter를 매개 변수로 전달합니다.따라서adapter를 설정하고 헤더를 추가하려면 추가할 수 없습니다.
여기서 이 버그가 발생한 원인에 대해 정확한 조작 절차는 먼저 소프트 키보드로 초점을 전환한 다음에 손가락으로 화면을 직접 클릭하는 것이다.이때 Android는 TouchModeChanged를 나타내는 이벤트를 생성합니다. 우리의 UI 구조는 아버지의 Activity가 있고 몇 개의 하위 인터페이스는 Tab 페이지처럼 부모 인터페이스에 표시되기 때문에 이 몇 개의 하위 인터페이스는 부모 인터페이스에서 보내는 이 이벤트를 받습니다.이것은 왜 현재 표시되지 않은 인터페이스에서도 이 메시지를 받고 일련의 동작을 할 수 있는지 설명한다.
물론 가장 주요한 원인은 바로 이 밑에 새로 고친 컨트롤러가 문제가 있는 것이다. (이 인터넷에는 이미 만들어진 것이 있지만 우리는 소스 코드를 사용할 수 없기 때문에 회사 내부에서 실현된 것이다.) 어디에 문제가 있겠는가
	listView = new ListView(context, attrs) {
            @Override
            public BaseAdapter getAdapter() {
                if (adapter != null) {
                    return adapter.getInnerAdapter();
                } else {
                    return null;
                }
            }

        };

인터페이스에서 구현된 Adapter가 반환됩니다. 왜 여기에 문제가 있습니까?그래서 헤더가 있는 ListView는 실제로 Header View List Adapter를 사용하는데 이렇게 해서 ListView를 어떻게 견딜 수 있겠는가.그리고 HeaderViewListAdapter는 getCount 등 함수를 다시 쓰고 헤더와footer의 수량을 자동으로 처리하기 때문에

좋은 웹페이지 즐겨찾기