You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将自定义Parcelable类添加至系统ClassLoader,全局解决Bundle异常?

全局解决自定义Parcelable的ClassLoader问题

老哥,我太懂你每次手动给Bundle设置ClassLoader的烦躁了——重复操作简直是浪费生命!确实有办法在应用层面一次性搞定这个问题,不用再每次都折腾。

先给你说下问题根源:系统在处理Bundle的序列化/反序列化时,有时候会默认使用系统类加载器,但你的自定义Parcelable类(A和B)是由应用自己的类加载器加载的,这就导致解包时找不到类,抛出BadParcelableException: ClassNotFoundException when unmarshalling。

下面给你两个全局解决方案,任选其一就行:

方案1:用Application的Activity生命周期回调(推荐,无需修改Activity继承)

直接在自定义Application里注册一个全局的Activity生命周期监听,自动给所有Activity的Bundle设置ClassLoader:

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
                // 恢复状态前给Bundle设置应用类加载器
                if (savedInstanceState != null) {
                    savedInstanceState.setClassLoader(activity.getClassLoader());
                }
            }

            @Override
            public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
                // 保存状态时提前设置好类加载器
                outState.setClassLoader(activity.getClassLoader());
            }

            // 其他生命周期方法留空即可
            @Override public void onActivityStarted(@NonNull Activity activity) {}
            @Override public void onActivityResumed(@NonNull Activity activity) {}
            @Override public void onActivityPaused(@NonNull Activity activity) {}
            @Override public void onActivityStopped(@NonNull Activity activity) {}
            @Override public void onActivityDestroyed(@NonNull Activity activity) {}
        });
    }
}

记得在AndroidManifest.xml里把Application指定为这个自定义类:

<application
    android:name=".MyApp"
    ...>
    ...
</application>

方案2:用基类Activity(适合已有统一基类的项目)

如果你的项目已经有一个所有Activity都继承的基类,直接在基类里重写状态保存和恢复的方法,统一设置ClassLoader:

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // 先给Bundle设置类加载器,再调用父类方法
        if (savedInstanceState != null) {
            savedInstanceState.setClassLoader(getClassLoader());
        }
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // 保存状态前设置类加载器
        outState.setClassLoader(getClassLoader());
        super.onSaveInstanceState(outState);
    }
}

之后所有Activity继承这个基类,就再也不用手动处理ClassLoader的问题了。

这两个方案都能从应用层面全局解决问题,以后不管是屏幕旋转还是其他需要保存Bundle的场景,都不会再出现那个烦人的ClassNotFoundException了。

内容的提问来源于stack exchange,提问作者Andriy Antonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:32:47