Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
hamsik2046 opened this issue Apr 21, 2016 · 15 comments

Comments

@hamsik2046
Copy link

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) 

@HomHomLin
Copy link
Owner

HomHomLin commented Apr 22, 2016

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.

@hamsik2046
Copy link
Author

并不是什么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;
    }

}`

@HomHomLin
Copy link
Owner

PullToRefreshBase是哪来的?

@MIkeeJY
Copy link

MIkeeJY commented Jul 19, 2016

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

@yonggege2013
Copy link

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

@MIkeeJY
Copy link

MIkeeJY commented Nov 24, 2016

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

@yonggege2013
Copy link

yonggege2013 commented Nov 28, 2016 via email

@MIkeeJY
Copy link

MIkeeJY commented Nov 28, 2016

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

@Froyo91
Copy link

Froyo91 commented Dec 14, 2016

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

@MIkeeJY
Copy link

MIkeeJY commented Dec 14, 2016

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

@yonggege2013
Copy link

yonggege2013 commented Dec 14, 2016 via email

@MIkeeJY
Copy link

MIkeeJY commented Dec 14, 2016

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

@xsyulinzi
Copy link

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

@humanheima
Copy link

humanheima commented Jan 15, 2018

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

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

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

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

@wuzhenjiang
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants