[英]Why is there ClassNotFoundException when i change screen orientation?
旋轉設備時出現ClassNotFoundException。 將admob庫com.google.android.gms:play-services-ads:17.2.0添加到我的項目后,發生了錯誤。 沒有這個庫,一切都會正常。
我試圖將庫版本更改為16.0.0,在此版本中不需要應用程序ID,不會發生錯誤。
2019-04-09 19:32:16.164 12689-12718/com.example.example.myapplication E/Parcel: Class not found when unmarshalling: android.support.v4.app.FragmentManagerState
java.lang.ClassNotFoundException: android.support.v4.app.FragmentManagerState
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:400)
at android.os.Parcel.readParcelableCreator(Parcel.java:2564)
at android.os.Parcel.readParcelable(Parcel.java:2518)
at android.os.Parcel.readValue(Parcel.java:2421)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2788)
at android.os.BaseBundle.unparcel(BaseBundle.java:271)
at android.os.Bundle.getBundle(Bundle.java:817)
at fw.onActivityCreated(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):33)
at com.google.android.gms.measurement.internal.AppMeasurementDynamiteService.onActivityCreated(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):145)
at cf.a(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):160)
at k.onTransact(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):4)
at android.os.Binder.transact(Binder.java:499)
at com.google.android.gms.internal.measurement.zzq.zza(Unknown Source)
at com.google.android.gms.internal.measurement.zzdp.onActivityCreated(Unknown Source)
at com.google.android.gms.internal.measurement.zzex.zzgd(Unknown Source)
at com.google.android.gms.internal.measurement.zzea$zzb.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
Caused by: java.lang.ClassNotFoundException: android.support.v4.app.FragmentManagerState
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:1346)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:1406)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:400)
at android.os.Parcel.readParcelableCreator(Parcel.java:2564)
at android.os.Parcel.readParcelable(Parcel.java:2518)
at android.os.Parcel.readValue(Parcel.java:2421)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2788)
at android.os.BaseBundle.unparcel(BaseBundle.java:271)
at android.os.Bundle.getBundle(Bundle.java:817)
at fw.onActivityCreated(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):33)
at com.google.android.gms.measurement.internal.AppMeasurementDynamiteService.onActivityCreated(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):145)
at cf.a(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):160)
at k.onTransact(:com.google.android.gms.dynamite_measurementdynamite@16089051@16.0.89 (040408-239467275):4)
at android.os.Binder.transact(Binder.java:499)
at com.google.android.gms.internal.measurement.zzq.zza(Unknown Source)
at com.google.android.gms.internal.measurement.zzdp.onActivityCreated(Unknown Source)
at com.google.android.gms.internal.measurement.zzex.zzgd(Unknown Source)
at com.google.android.gms.internal.measurement.zzea$zzb.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:760)
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
我的MainActivity.java是
public class MainActivity extends AppCompatActivity {
final Fragment[] fragments = new Fragment[3];
BottomNavigationView navView;
FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713");
fragmentManager = getSupportFragmentManager();
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(getString(R.string.app_name));
toolbar.setTitleTextColor(Color.WHITE);
toolbar.setNavigationIcon(R.drawable.ic_navigation);
navView = findViewById(R.id.nav_view);
AdView adView = findViewById(R.id.adView);
adView.loadAd(new AdRequest.Builder().build());
fragments[0] = new RandomFragment();
fragments[1] = new FullListFragment();
fragments[2] = new FavoriteFragment();
fragmentManager.beginTransaction().add(R.id.main_container2, fragments[0]).commit();
navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
Fragment fragment;
switch (menuItem.getItemId()) {
case R.id.navigation_home:
fragment = fragments[0];
break;
case R.id.navigation_dashboard:
fragment = fragments[1];
break;
case R.id.navigation_notifications:
fragment = fragments[2];
break;
default:
fragment = fragments[0];
break;
}
fragmentManager.beginTransaction().replace(R.id.main_container2, fragment).commit();
return true;
}
});
navView.setSelectedItemId(R.id.navigation_home);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("SelectedItemId", navView.getSelectedItemId());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int selectedItemId = savedInstanceState.getInt("SelectedItemId");
navView.setSelectedItemId(selectedItemId);
}
}
旋轉后,您的SupportMapFragment被銷毀並重新創建。 在銷毀它之前,它將其當前狀態寫入一個宗地,以便在重新創建時恢復其狀態。 Fragment的保存狀態將包括其子視圖的狀態,並且由於您已在其中嵌套了AdMob視圖 ,因此它也會嘗試保存和還原該視圖 。 AdMob沒有為此所需的內部類SavedState,因此,當嘗試從Parcel還原AdMob實例時,此過程將失敗。
解決方案是不要在該元素內嵌套AdMob或任何其他視圖。
這是您可以做的,就像黑客一樣
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
AdView adView = (AdView)findViewById(R.id.adView);
View contentFrame = findViewById(R.id.contentFrameLayout);
RelativeLayout parent = (RelativeLayout) adView.getParent();
LayoutParams mapFrameParams = contentFrame.getLayoutParams();
LayoutParams adViewParams = adView.getLayoutParams();
parent.removeView(adView);
parent.removeView(contentFrame);
AdView newAdView = new AdView(this, AdSize.SMART_BANNER, getString(R.string.admob_pubId));
newAdView.setId(R.id.adView);
parent.addView(newAdView, adViewParams);
parent.addView(contentFrame,mapFrameParams);
newAdView.loadAd(new AdRequest());
}
經過最長的思考。 我有答案。 在新庫中,添加了具有應用程序ID的ads初始化方法的witch沒有內部類SavedState。 因此,所有需要的都是像這樣保存appid:
private static final String APP_ID = "your_app_id"
@Override
protected void onCreate(Bundle savedInstanceState) {
Bundle adsInstanceState = (savedInstanceState != null)
? savedInstanceState.getBundle(APP_ID): null;
super.onCreate(adsInstanceState);
MobileAds.initialize(this,APP_ID);
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
Bundle adsInstanceState = new Bundle();
outState.putBundle(APP_ID, adsInstanceState )
}
類似的問題,但有地圖: https : //stackoverflow.com/a/36818004/11334749希望對某人有幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.