2

У меня проблема с моим пользовательским фрагментом с MapView и CoordinatorLayout. Я сделал простое приложение, чтобы проиллюстрировать его. Я также попытался сделать то же самое на стандартной демонстрации Google API, и там не было проблем, но, вероятно, это потому, что они используют MapFragment, но не MapView.Сбой MapView во фрагменте с компоновкой координатора при изменении конфигурации

Ниже я загрузил код и макеты. В конце также была вставлена ​​ошибка.

public class BlankFragment extends Fragment implements OnMapReadyCallback { 

    private MapView mapView; 
    private Bundle BundleForMap; 

    @Override 
    public void onMapReady(GoogleMap googleMap) { } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     BundleForMap = savedInstanceState; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_blank, container, false); 

     mapView = (MapView) view.findViewById(R.id.map_event_mapview); 
     mapView.onCreate(BundleForMap); 
     mapView.getMapAsync(this); 
     return view; 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     mapView.onResume(); 
    } 

    @Override 
    public void onPause() { 

     super.onPause(); 
     mapView.onPause(); 
    } 

    @Override 
    public void onDestroy() { 
     mapView.onDestroy(); 
     super.onDestroy(); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     mapView.onLowMemory(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
     mapView.onSaveInstanceState(savedInstanceState); 
     super.onSaveInstanceState(savedInstanceState); 
    } 

} 

активность просто просто вызывает этот фрагмент и заменяет вид контейнера с ним:

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     FragmentManager fragmentManager = getFragmentManager(); 
     FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

     BlankFragment blankFragment = new BlankFragment(); 
     fragmentTransaction.replace(R.id.container, blankFragment, ""); 

     fragmentTransaction.commit(); 

    } 

А вот макет фрагмента:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.mapview_test.BlankFragment"> 

    <com.google.android.gms.maps.MapView 
     android:id="@+id/map_event_mapview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 

    <android.support.design.widget.CoordinatorLayout 
     android:id="@+id/map_event_bottom_sheet" 
     android:layout_height="match_parent" 
     android:layout_width="match_parent" > 

     <android.support.v4.widget.NestedScrollView 
      android:id="@+id/bottom_sheet" 
      android:layout_width="match_parent" 
      android:layout_height="175dp" 
      android:elevation="16dp" 
      android:outlineProvider="bounds" 
      android:background="@android:color/white" 
      > 

      <TextView 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:padding="16dp" 
       android:textSize="16sp" 
       android:id="@+id/testText"/> 

     </android.support.v4.widget.NestedScrollView> 

    </android.support.design.widget.CoordinatorLayout> 

</FrameLayout> 

Проблема, очевидно, с макетом координатора и как он имеет паркет.

Process: com.example.alovita.mapview_test, PID: 12989 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.alovita.mapview_test/com.example.alovita.mapview_test.MainActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.design.widget.CoordinatorLayout$SavedState 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3992) 
at android.app.ActivityThread.access$1000(ActivityThread.java:154) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5310) 
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:904) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.design.widget.CoordinatorLayout$SavedState 
at android.os.Parcel.readParcelableCreator(Parcel.java:2295) 
at android.os.Parcel.readParcelable(Parcel.java:2245) 
at android.os.Parcel.readValue(Parcel.java:2152) 
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2546) 
at android.os.Parcel.readSparseArray(Parcel.java:1874) 
at android.os.Parcel.readValue(Parcel.java:2209) 
at android.os.Parcel.readArrayMapInternal(Parcel.java:2485) 
at android.os.BaseBundle.unparcel(BaseBundle.java:221) 
at android.os.Bundle.getBundle(Bundle.java:733) 
at aac.a(:com.google.android.gms.DynamiteModulesB:74) 
at maps.ad.u.a(Unknown Source) 
at maps.ad.R.a(Unknown Source) 
at wc.onTransact(:com.google.android.gms.DynamiteModulesB:66) 
at android.os.Binder.transact(Binder.java:380) 
at com.google.android.gms.maps.internal.IMapViewDelegate$zza$zza.onCreate(Unknown Source) 
at com.google.android.gms.maps.MapView$zza.onCreate(Unknown Source) 
at com.google.android.gms.dynamic.zza$3.zzb(Unknown Source) 
at com.google.android.gms.dynamic.zza$1.zza(Unknown Source) 
at com.google.android.gms.maps.MapView$zzb.zzbow(Unknown Source) 
at com.google.android.gms.maps.MapView$zzb.zza(Unknown Source) 
at com.google.android.gms.dynamic.zza.zza(Unknown Source) 
at com.google.android.gms.dynamic.zza.onCreate(Unknown Source) 
at com.google.android.gms.maps.MapView.onCreate(Unknown Source) 
at com.example.alovita.mapview_test.BlankFragment.onCreateView(BlankFragment.java:45) 
at android.app.Fragment.performCreateView(Fragment.java:2053) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1049) 
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1869) 
at android.app.Activity.performCreateCommon(Activity.java:6860) 
at android.app.Activity.performCreate(Activity.java:6867) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432)  
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3992)  
at android.app.ActivityThread.access$1000(ActivityThread.java:154)  
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327)  
at android.os.Handler.dispatchMessage(Handler.java:102)  
at android.os.Looper.loop(Looper.java:135)  
at android.app.ActivityThread.main(ActivityThread.java:5310)  
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:904)  
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)  

Проблема с этой линии:

mapView.onCreate(BundleForMap); 

При изменении конфигурации экрана, этот параметр явно не null и приложение разбился. При прохождении здесь null вместо пучка, он отлично работает. Когда я удаляю CoordinatorLayout, приложение работает нормально.

Вот моя зависимость:

android { 
    compileSdkVersion 24 
    buildToolsVersion "24.0.1" 

    defaultConfig { 
     applicationId "com.example.mapview_test" 
     minSdkVersion 22 
     targetSdkVersion 24 
     versionCode 1 
     versionName "1.0" 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 
    compile 'com.android.support:appcompat-v7:24.2.0' 
    compile 'com.android.support:support-v4:24.2.0' 
    compile 'com.android.support:recyclerview-v7:24.2.0' 
    compile 'com.android.support:design:24.2.0' 
    compile 'com.google.android.gms:play-services-appindexing:9.4.0' 
    compile 'com.google.android.gms:play-services-maps:9.4.0' 
    compile 'com.google.android.gms:play-services-location:9.4.0' 
} 

Я застрял с этим из долгого времени. Любая помощь будет оценена

ответ

1

Кажется, это хорошо известная проблема: Android Issue 6237

Я выполнил свое собственное решение, основанное на этом ответе: Android Issue 6237 #C9

Реализация выглядит следующим образом (на основе #C9 ответа):

Мне удалось обойти его, сохранив сохраненное состояние MapView на отдельном комплекте и затем добавив его в исходящий сохраненный пакет состояния. Затем в onCreate() я просто захватил сохраненное состояние MapView из входящего и передал его в свой метод onCreate(), тем самым прекратив сбои.

@Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
     final Bundle mapViewSaveState = new Bundle(savedInstanceState); 
     mapView.onSaveInstanceState(mapViewSaveState); 
     savedInstanceState.putBundle("mapViewSaveState", mapViewSaveState); 

     Bundle customBundle = new Bundle(); 
     // put custom objects if needed to customBundle 

     savedInstanceState.putBundle(ARG_CUSTOM_BUNDLE, customBundle); 
     super.onSaveInstanceState(savedInstanceState); 
    } 

И затем, использовать, что mapViewSaveState в onCreate (или onCreateView, если он представляет собой фрагмент):

mapView.onCreate(savedInstanceState != null ? savedInstanceState.getBundle("mapViewSaveState") : null); 
+0

У меня была та же проблема с 'Activity' с' DrawerLayout', что содержал «FrameLayout», а мой «Фрагмент», содержащий «MapView», был просто «FrameLayout» ... Кажется, он исправил его, так что спасибо! Я не знаю, как вы это поняли! – NineToeNerd