解组时找不到类:android.support.v7.widget.Toolbar $ SavedState

时间:2016-04-23 12:49:40

标签: java android xml api maps

我使用Maps API创建一个简单的Android应用程序,我得到一个我无法解决的奇怪错误。它通常发生在我旋转设备时。我正在使用谷歌服务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

我的MainActivity.java是

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是

<?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是

<?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>

最后,toolbar.xml是

<?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>

4 个答案:

答案 0 :(得分:9)

我不喜欢提供的解决方案,因为它强加于我的布局和架构。

这就是我做的工作。如果查看堆栈跟踪,ClassNotFoundException将来自GoogleMaps上的一行。因此,如果我们解决这个问题,问题就会消失。

GoogleMaps pukes /在savedInstanceState中包含其他项目时会抛出错误。解决方案是给GoogleMaps自己专用的捆绑包。

// class property
private static final String KEY_MAP_SAVED_STATE = "mapState";

// class methods
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mapView = findMapView();  // make your own method here
    Bundle mapState = (savedInstanceState != null)
            ? savedInstanceState.getBundle(KEY_MAP_SAVED_STATE): null;
    mapView.onCreate(mapState);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Bundle mapState = new Bundle();
    mapView.onSaveInstanceState(mapState);
    outState.putBundle(KEY_MAP_SAVED_STATE, mapState);
}

需要注意的一点是我没有使用SupportMapFragment。我正在使用MapView。您可能必须扩展SupportMapFragment,以便捕获钩子方法并提供空白/清理包

答案 1 :(得分:3)

轮换后,您的SupportMapFragment会被销毁并重新创建。在它被销毁之前,它会将其当前状态写入Parcel,以便在重新创建时用于恢复其状态。 Fragment已保存状态将包含其子View的状态,并且由于您已在其中嵌套了Toolbar,因此它也会尝试保存和恢复该状态。 Toolbar类没有必要的内部类SavedState,因此尝试从Toolbar恢复Parcel实例时此过程失败。

解决方案是不在Toolbar元素内嵌套View - 或任何其他<fragment>。相反,将<include>拉出<fragment>,并将它们放在另一个ViewGroup中;例如,垂直LinearLayoutRelativeLayout

答案 2 :(得分:2)

将activity_map.xml更改为此工作,再次感谢Mike。

<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

    <fragment 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">

    </fragment>
</RelativeLayout>

答案 3 :(得分:0)

我的自定义视图存在类似的问题,并找到了this解决方案。 我注意到,当我扩展 RecyclerView AppCompatSpinner 并需要保存状态时,就会发生此崩溃。崩溃也可能发生在其他视图上。

基本上,崩溃是由here中提到的AbsSavedState中的错误引起的。 只有在没有类加载器的情况下调用SavedState的构造函数时,才会发生崩溃。看来这是一个老问题,但是我开始获取Android 9和10的崩溃报告。

所以解决方法是更改​​:

public SavedState(Parcel source) {
  super(source);
  //... 
}

收件人:

public SavedState(Parcel source) {
  super(source, LinearLayoutManager.class.getClassLoader());
  //... 
}

修改 我在正确的轨道上,但是随后我看着一些Android code,发现实际上缺少构造函数,导致崩溃。因此,我为SavedState使用了以下构造函数:

SavedState(Parcel in)
{
    super(in);
    //...
}

我需要添加以下内容:

@RequiresApi(Build.VERSION_CODES.N)
SavedState(Parcel in, ClassLoader loader)
{
    super(in, loader);
    //...
}

然后我需要更改创建者:

public static final Creator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>()
{
    @Override
    public SavedState createFromParcel(Parcel source, ClassLoader loader)
    {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new SavedState(source, loader) : new SavedState(source);
    }

    @Override
    public SavedState createFromParcel(Parcel source)
    {
        return createFromParcel(source, null);
    }

    public SavedState[] newArray(int size)
    {
        return new SavedState[size];
    }
};