【问题标题】:Why is there ClassNotFoundException when i change screen orientation?为什么更改屏幕方向时出现 ClassNotFoundException?
【发布时间】:2019-04-09 16:49:27
【问题描述】:

我在旋转设备时收到 ClassNotFoundException。在我将 admob 库 com.google.android.gms:play-services-ads:17.2.0 添加到我的项目后发生错误。没有这个库一切正常。

我尝试将库版本更改为不需要应用程序 ID 的 16.0.0,没有发生错误。

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);
    }


}

【问题讨论】:

    标签: java android android-fragments admob


    【解决方案1】:

    经过最长的思考。我有答案了。 在新库中添加了带有 app id 的广告初始化方法,女巫没有内部类 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 希望这对某人有所帮助

    【讨论】:

      【解决方案2】:

      旋转时,您的 SupportMapFragment 会被销毁并重新创建。在它被销毁之前,它会将其当前状态写入一个 Parcel,以便在重新创建时用于恢复其状态。 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());
      }
      

      【讨论】:

      • 我还没有添加任何 AdView。但是,我在清单中注册了应用程序 ID,例如 <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="@string/app_id" />,这是 admob 库所必需的。将此添加到清单后,出现上述错误。
      • 你能在片段代码中尝试这样的事情吗 Override public void onResume() { super.onResume(); if (newAdView!= null) { AdRequest adRequest = new AdRequest.Builder().build(); newAdView.loadAd(adRequest); } } 覆盖 public void onPause() { newAdView.pause();超级.onPause(); } 覆盖 public void onDestroy() { newAdView.destroy(); super.onDestroy(); }
      猜你喜欢
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多