Android-PullToRefreshRecyclerView icon indicating copy to clipboard operation
Android-PullToRefreshRecyclerView copied to clipboard

Wrong state class, expecting View State but received class android.support.v7.widget.RecyclerView$SavedState instead

Open hamsik2046 opened this issue 9 years ago • 15 comments

Process: com.haimai.baletu, PID: 27332 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.haimai.baletu/com.haimai.main.activity.MainActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.support.v7.widget.RecyclerView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/main_house_list_recyclerview. Make sure other views do not use the same id. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2330) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392) at android.app.ActivityThread.access$800(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5279) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:910) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:705) Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.support.v7.widget.RecyclerView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/main_house_list_recyclerview. Make sure other views do not use the same id. at android.view.View.onRestoreInstanceState(View.java:13807) at com.handmark.pulltorefresh.library.PullToRefreshBase.onRestoreInstanceState(PullToRefreshBase.java:833) at android.view.View.dispatchRestoreInstanceState(View.java:13783) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2888) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) at android.view.View.restoreHierarchyState(View.java:13761) at android.support.v4.app.Fragment.restoreViewState(Fragment.java:471) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1105) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1241) at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2053) at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1979) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1259) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1241) at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2053) at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:165) at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:543) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236) at android.app.Activity.performStart(Activity.java:6065) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)  at android.app.ActivityThread.access$800(ActivityThread.java:154)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:135)  at android.app.ActivityThread.main(ActivityThread.java:5279)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:910)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:705) 

hamsik2046 avatar Apr 21 '16 07:04 hamsik2046

Can you please share a snippet of your code? It said that two views of different type have the same id in your project. You could check the views in your project which use R.id.main_house_list_recyclerview for view's id. Also, you could try to clean your project and rebuild it.

HomHomLin avatar Apr 22 '16 02:04 HomHomLin

并不是什么id重复的问题,小哥你可以试一试,蛮容易重现的: 直接留在列表页,按home键app去后台,然后开几个耗内存的应用,这时候列表页面会被回收,触发onSaveInstanceState方法,然后再点击app,切回前台,又进入列表页的onRestoreInstanceState方法,就会触发这个bug。

PullToRefreshBase重写的onRestoreInstanceState方法里,没有instanceof判断state类型和是否非空,导致最后走到父类的onRestoreInstanceState方法时,抛出了IllegalArgumentException异常

======PullToRefreshBase重写的onRestoreInstanceState方法================= `@Override protected final void onRestoreInstanceState(Parcelable state) { if (state instanceof Bundle) { Bundle bundle = (Bundle) state;

    setMode(Mode.mapIntToValue(bundle.getInt(STATE_MODE, 0)));
    mCurrentMode = Mode.mapIntToValue(bundle.getInt(STATE_CURRENT_MODE, 0));

    mScrollingWhileRefreshingEnabled = bundle.getBoolean(STATE_SCROLLING_REFRESHING_ENABLED, false);
    mShowViewWhileRefreshing = bundle.getBoolean(STATE_SHOW_REFRESHING_VIEW, true);

    // Let super Restore Itself
    super.onRestoreInstanceState(bundle.getParcelable(STATE_SUPER));

    State viewState = State.mapIntToValue(bundle.getInt(STATE_STATE, 0));
    if (viewState == State.REFRESHING || viewState == State.MANUAL_REFRESHING) {
        setState(viewState, true);
    }

    // Now let derivative classes restore their state
    onPtrRestoreInstanceState(bundle);
    return;
}

super.onRestoreInstanceState(state);

}`

====================父类的onRestoreInstanceState方法======================

`@CallSuper protected void onRestoreInstanceState(Parcelable state) { mPrivateFlags |= PFLAG_SAVE_STATE_CALLED; if (state != null && !(state instanceof AbsSavedState)) { throw new IllegalArgumentException("Wrong state class, expecting View State but "

  • "received " + state.getClass().toString() + " instead. This usually happens "
  • "when two views of different type have the same id in the same hierarchy. "
  • "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure "
  • "other views do not use the same id."); } if (state != null && state instanceof BaseSavedState) { mStartActivityRequestWho = ((BaseSavedState) state).mStartActivityRequestWhoSaved; }

}`

hamsik2046 avatar May 12 '16 06:05 hamsik2046

PullToRefreshBase是哪来的?

HomHomLin avatar May 12 '16 06:05 HomHomLin

@hamsik2046 @HomHomLin 换成findViewWithTag 应该就没事了,也不需要修改顶层代码

MIkeeJY avatar Jul 19 '16 04:07 MIkeeJY

这个问题究竟怎样去解决???

yonggege2013 avatar Nov 24 '16 08:11 yonggege2013

@yonggege2013 findViewWithTag 初始化用这个不用findviewbyid就没事额

MIkeeJY avatar Nov 24 '16 10:11 MIkeeJY

你是说不用id,用tag表示,tag在哪里设置呢

发自网易邮箱大师 在2016年11月24日 18:22,MIkeeJY 写道:

@yonggege2013 findViewWithTag 初始化用这个不用findviewbyid就没事额

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

yonggege2013 avatar Nov 28 '16 02:11 yonggege2013

@yonggege2013 写布局的时候用 android tag不用android id,然后加载布局的时候findviewwithtag。。。

MIkeeJY avatar Nov 28 '16 02:11 MIkeeJY

@MIkeeJY 你好,请问使用tag可以解决这个bug的依据是什么额?

Froyo91 avatar Dec 14 '16 07:12 Froyo91

@Froyo91 因为提示是id冲突了 虽然你布局里没有重复id 所以我改成了tag去findview了 就没问题了。

MIkeeJY avatar Dec 14 '16 07:12 MIkeeJY

一开始我的布局里面没法用tag 标签啊

发自网易邮箱大师 在2016年11月24日 18:22,MIkeeJY 写道:

@yonggege2013 findViewWithTag 初始化用这个不用findviewbyid就没事额

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

yonggege2013 avatar Dec 14 '16 08:12 yonggege2013

@yonggege2013 xml里设置这个 android:tag="ptr_recycler" 代码里set tag

MIkeeJY avatar Dec 14 '16 08:12 MIkeeJY

@HomHomLin 这个问题是在PullToRefreshRecyclerView类createRefreshableView方法中动态创建RecyclerView时没有设置id,但是在创建scrollview、webview、listview、gridview等时作者都有设置id,唯独创建recyclerview时没有设置,请问这里没设置id是遗漏还是有其他原因,还请作者解释下,谢谢

xsyulinzi avatar Sep 16 '17 04:09 xsyulinzi

我在Fragment里面用的下拉刷新的库是这个https://github.com/hehonghui/Chris-Android-PullToRefresh

也有这个问题。在PullToRefreshRecyclerView中创建recyclerview 的时候指定一下id就行了。

RecyclerView recyclerView = new RecyclerView(context, attrs); recyclerView.setId(R.id.recyclerview); return recyclerView;

但是具体的原因我也不知道

humanheima avatar Jan 15 '18 09:01 humanheima

问题是否解决了?要是解决了方便告诉一下解决方案吗

wuzhenjiang avatar Oct 11 '18 11:10 wuzhenjiang