In my MainActivity
I call this code to change to a new fragment, I pass a bundle with parcelable object, itemModel
to the fragment:
Bundle bundle = new Bundle();
bundle.putParcelable(ItemModel.ParcelableKey, itemModel);
fragment = new AppFragment();
fragment.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, fragment).addToBackStack(null).commit();
In the fragment, I receive the parcel back like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey);
//....other code.....
}
When I test it locally, the code works fine on my test device, mItemModel
is able to be retrieved back properly, however, I have integrated crash report system into the app (Crashlytics), and the report states a log like this on a release:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.temp.test/com.temp.test.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
at android.app.ActivityThread.access$700(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4960)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.NullPointerException
at android.os.Parcel.readStringArray(Parcel.java:931)
at com.temp.test.data.ItemModel.<init>(ItemModel.java:478)
at com.temp.test.data.ItemModel.<init>(ItemModel.java:23)
at com.temp.test.data.ItemModel$1.createFromParcel(ItemModel.java:445)
at com.temp.test.data.ItemModel$1.createFromParcel(ItemModel.java:443)
at android.os.Parcel.readParcelable(Parcel.java:2103)
at android.os.Parcel.readValue(Parcel.java:1965)
at android.os.Parcel.readMapInternal(Parcel.java:2226)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1165)
at com.temp.test.fragments.AppFragment.onCreateView(AppFragment.java:98)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
at android.app.FragmentManagerImpl.moveTo## Heading ##State(FragmentManager.java:1035)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1804)
at android.app.Activity.performCreate(Activity.java:5206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
at android.app.ActivityThread.access$700(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4960)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(NativeStart.java)
at com.temp.test.fragments.AppFragment.onCreateView(AppFragment.java:98)
<-- This error line leads to this line in the source code:
mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey);
It is very strange because it works well in my local device. So I dived a little deeper into Bundle
's source code, I noticed that in unparcel()
, it has a checking like this at the beginning:
synchronized void unparcel() {
if (mParcelledData == null) {
if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": no parcelled data");
return;
}
//....other code.....
}
The strange thing is that mParcelledData
should be null
in my case, because I created Bundle
like this Bundle bundle = new Bundle();
as shown in my code snippet above, so in my case it should be using mMap
instead of mParcelledData
.
Question: what are the possible cases that getArguments()
in fragment's onCreateView()
will return a Bundle
with non-null mParcelledData
?
OR
In what cases that mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey);
will perform differently in my local test device vs production release for end user?