Reputation: 2005
I think it is due to low memory if I set the app background.
The log is like below:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.qingdaonews.bus/com.qingdaonews.activity.RealTime}:
java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.view.View$BaseSavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/myviewpager. Make sure other views do not use the same id.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2266)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2316)
at android.app.ActivityThread.access$600(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5225)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
at dalvik.system.NativeStart.main(Native Method)
It looks like due to the same id of a view.In fact ,the id 'myviewpager' only appear once in the xml file and the problem only occur when the app is reopen from background.
And my MainActivity has one fragment which can be replaced in it.I use getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
when I start the activity.
Without super method of 'savedInstanceState',I did not use something else.
Upvotes: 3
Views: 3434
Reputation: 6488
We had this problem with low memory conditions (Dev settings -> "Do not keep activities" set) and custom views crashing while trying to do a restore of custom vies (overriding View.onRestoreInstanceState()
) As specified here. Views had no duplicate IDs.
A bug in the way the fragment was being restored (that contained the custom view), caused it to add different views at runtime while restoring, than was added when saving the instance state. (In our case a read write version of the custom view was added initially, but restoring the fragment added the read-only version of the view.)
I suspect Android then tries to set the state of the read-write views on the read-only views, and this breaks things.
This was observed on Android 4.4.4 but not Android 6.0.1
Exception we got was:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package.name/com.package.name.VisitActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class com.package.name.view.CustomView$CustomViewState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x465127ed. Make sure other views do not use the same id.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2413)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2471)
at android.app.ActivityThread.access$900(ActivityThread.java:175)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5602)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Upvotes: 1
Reputation: 3334
The cause is that your Fragment gets re-added. Your code looks like this:
protected void onCreate(Bundle savedInstanceState){
super(savedInstanceState);
///...
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_frame, fragment).commit();
}
Associated FragmentManager gets restored if savedInstanceState != null
via a call to super(savedInstanceState)
, and all the commited fragments get restored too. Instead, check if your fragment is already added, and add it only if not:
public class MyActivity extends Activity{
private MyFragment myFragment;//extends Fragment
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//your stuff
FragmentManager fm = getFragmentManager();
myFragment = (MyFragment) fm.findFragmentByTag(MyFragment.TAG);
if(myFragment == null){
myFragment = new MyFragment();
fm.beginTransaction()
.add(R.id.content_frame, myFragment, MyFragment.TAG)
.commit();
}
//other stuff
}
}
And in your MyFragment
, TAG is:
public static final String TAG = MyFragment.class.getSimpleName();
As for me, I found it is a nice practice to add Fragments with TAG parameter provided.
Upvotes: 3