i am using Maps API to create a simple android app and i get a wierd error i can't solve. It usually happens when i rotate my device. I'm using google services 8.4.0
4-23 15:39:47.503 9419-9419/com.licenta.vladut.mmap E/Parcel: Class not found when unmarshalling: android.support.v7.widget.Toolbar$SavedState
java.lang.ClassNotFoundException: android.support.v7.widget.Toolbar$SavedState
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:308)
at android.os.Parcel.readParcelableCreator(Parcel.java:2275)
at android.os.Parcel.readParcelable(Parcel.java:2239)
at android.os.Parcel.readValue(Parcel.java:2146)
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2540)
at android.os.Parcel.readSparseArray(Parcel.java:1868)
at android.os.Parcel.readValue(Parcel.java:2203)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2479)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getBundle(Bundle.java:782)
at com.google.android.gms.maps.internal.ao.a(:com.google.android.gms.alldynamite:74)
at maps.ei.bu.a(Unknown Source)
at maps.ei.n.a(Unknown Source)
at com.google.android.gms.maps.internal.i$a.onTransact(:com.google.android.gms.alldynamite:107)
at android.os.Binder.transact(Binder.java:380)
at com.google.android.gms.maps.internal.IMapFragmentDelegate$zza$zza.onCreateView(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment$zza.onCreateView(Unknown Source)
at com.google.android.gms.dynamic.zza$4.zzb(Unknown Source)
at com.google.android.gms.dynamic.zza.zza(Unknown Source)
at com.google.android.gms.dynamic.zza.onCreateView(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment.onCreateView(Unknown Source)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1230)
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2315)
at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:120)
at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:357)
at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:80)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136)
at com.licenta.vladut.mmap.MainActivity.onCreate(MainActivity.java:54)
at android.app.Activity.performCreate(Activity.java:6020)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2259)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3947)
at android.app.ActivityThread.access$900(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1290)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
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:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.Toolbar$SavedState" on path: DexPathList[[zip file "/data/data/com.google.android.gms/app_chimera/m/00000000/DynamiteModules-prod.apk"],nativeLibraryDirectories=[/data/data/com.google.android.gms/app_chimera/m/00000000/n/armeabi-v7a, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.f
04-23 15:39:47.503 9419-9419/com.licenta.vladut.mmap D/AndroidRuntime: Shutting down VM
04-23 15:39:47.505 9419-9419/com.licenta.vladut.mmap E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.licenta.vladut.mmap, PID: 9419
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.licenta.vladut.mmap/com.licenta.vladut.mmap.MainActivity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2306)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3947)
at android.app.ActivityThread.access$900(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1290)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
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:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:276)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:136)
at com.licenta.vladut.mmap.MainActivity.onCreate(MainActivity.java:54)
at android.app.Activity.performCreate(Activity.java:6020)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2259)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3947)
at android.app.ActivityThread.access$900(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1290)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5292)
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:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v7.widget.Toolbar$SavedState
at android.os.Parcel.readParcelableCreator(Parcel.java:2289)
at android.os.Parcel.readParcelable(Parcel.java:2239)
at android.os.Parcel.readValue(Parcel.java:2146)
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2540)
at android.os.Parcel.readSparseArray(Parcel.java:1868)
at android.os.Parcel.readValue(Parcel.java:2203)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2479)
at android.os.BaseBundle.unparcel(BaseBundle.java:221)
at android.os.Bundle.getBundle(Bundle.java:782)
at com.google.android.gms.maps.internal.ao.a(:com.google.android.gms.alldynamite:74)
at maps.ei.bu.a(Unknown Source)
at maps.ei.n.a(Unknown Source)
at com.google.android.gms.maps.internal.i$a.onTransact(:com.google.android.gms.alldynamite:107)
at android.os.Binder.transact(Binder.java:380)
at com.google.android.gms.maps.internal.IMapFragmentDelegate$zza$zza.onCreateView(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment$zza.onCreateView(Unknown Source)
at com.google.android.gms.dynamic.zza$4.zzb(Unknown Source)
at com.google.android.gms.dynamic.zza.zza(Unknown Source)
at com.google.android.gms.dynamic.zza.onCreateView(Unknown Source)
at com.google.android.gms.maps.SupportMapFragment.onCreateView(Unknown Source)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1230)
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2315)
at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:120)
at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:357)
at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:80)
at android.view.LayoutInf
My MainActivity.java is
package com.licenta.vladut.mmap;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, OnMapReadyCallback {
GoogleMap mMap;
private static final double BM_LAT = 47.6595076, BM_LNG = 23.5631243;
private Toolbar toolbar;
private GoogleApiClient mGoogleApiClient;
private static final String TAG = "SignInActivity";
private static final int ERROR_DIALOG_REQUEST = 9001;
private static final int RC_SIGN_IN = 9002;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.addApi(AppIndex.API).build();
if (checkPlayServices()) {
setContentView(R.layout.activity_map);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
(MainActivity.this).setSupportActionBar(toolbar);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
} else {
setContentView(R.layout.activity_main);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.sign_out) {
signOut();
return true;
}
return super.onOptionsItemSelected(item);
}
private void signOut() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
toSignIn();
}
});
}
private void toSignIn() {
Intent i = new Intent(this, SignInActivity.class);
startActivity(i);
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// An unresolvable error has occurred and Google APIs (including Sign-In) will not
// be available.
Log.d(TAG, getString(R.string.onConnectionFailed) + connectionResult);
}
private boolean checkPlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if (result != ConnectionResult.SUCCESS) {
if (googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
ERROR_DIALOG_REQUEST).show();
} else {
Toast.makeText(this, "Nu se poate conecta la Google Play Services!", Toast.LENGTH_SHORT).show();
}
return false;
}
return true;
}
@Override
public void onMapReady(final GoogleMap map) {
this.mMap = map;
gotoLocation(BM_LAT,BM_LNG,18);
}
private void gotoLocation(double lat, double lng, float zoom){
LatLng latLng = new LatLng(lat, lng);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng,zoom);
mMap.moveCamera(update);
}
}
Activity_main.xml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
tools:context="com.licenta.vladut.mmap.MainActivity">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
/>
</RelativeLayout>
activity_map.xml is
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
/>
</fragment>
and finally, toolbar.xml is
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
android:background="?attr/colorPrimary"
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_alignParentStart="true"
android:elevation="4dp"
app:popupTheme="@style/AppTheme.PopupOverlay"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
</android.support.v7.widget.Toolbar>
Changing activity_map.xml to this worked, thanks again Mike.
I didn't like provided solutions as it imposed on my layouts and architecture.
Here's what I did to make it work. If you look at your stacktrace the ClassNotFoundException is coming from the line on GoogleMaps. So if we just fix that, the issue is gone.
GoogleMaps pukes/throw an error when the savedInstanceState has other items in it besides it's own. The solution is to just give GoogleMaps it's own dedicated bundle.
One thing to note is I'm not using the SupportMapFragment. I'm using a MapView directly. You may have to extend the SupportMapFragment so you can catch the hook methods and provide a blank/clean bundle
Upon rotation, your
SupportMapFragment
gets destroyed and recreated. Before it's destroyed, it writes its current state to aParcel
, to be used in restoring its state when recreated. TheFragment
's saved state will include the state of its childView
s, and since you've nested aToolbar
within it, it attempts to save and restore that, as well. TheToolbar
class does not have an inner classSavedState
necessary for that, so this process fails when trying to restore theToolbar
instance from theParcel
.The solution is to not nest the
Toolbar
- or any otherView
, for that matter - within the<fragment>
element. Instead, pull the<include>
out of the<fragment>
, and put them both in anotherViewGroup
; for example, a verticalLinearLayout
, or aRelativeLayout
.I had a similar problem with my custom view and found this solution. I noticed that this crash occurred when I extended RecyclerView or AppCompatSpinner and needed to save the state. The crash will probably happen for other views as well.
Basically the crash is caused by a bug in AbsSavedState as mentioned here. And the crash only occurs when the constructor of the SavedState is called without a class loader. It seemed like this was an old issue however I started getting crash reports for Android 9 and 10.
So the fix was to change:
to:
Edit I was on the right track, but then I was looking at some Android code and found out that there was actually a constructor missing that caused the crash. So I had the following constructor for the SavedState:
And I needed to add the following:
And then I needed to change the creator: