环境
- Replugin插件框架
问题原因
问题原因的分析这段文字没有经过润色,纯粹是初稿,不一定易于阅读,这段看不下去的同学可以直接看文章最后的解决方案。
ReportFragment
是android.arch.lifecycle
组件中的类,lifecycle
组件中的ProcessLifecycleOwnerInitializer
继承自ContentProvider
,利用ContentProvider#onCreate()
方法初始化。
在初始化时,通过Application#registerActivityLifecycleCallbacks()
注册Activity
的生命周期监听,在onActivityCreated()
回调中为每一个Activity
注入一个ReportFragment
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner should always correctly work and some activities may not extend
// FragmentActivity from support lib, so we use framework fragments for activities
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
注入ReportFragment
之后,ProcessLifecycleOwner
中也会监听Activity
的生命周期,并且在onActivityCreated()
回调中通过ReportFragment.get()
方法获取ReportFragment
。
static ReportFragment get(Activity activity) {
return (ReportFragment) activity.getFragmentManager().findFragmentByTag(
REPORT_FRAGMENT_TAG);
}
出错的代码就是get()
方法中的转型。
ReportFragment
为什么不能被转型成ReportFragment
呢?因为它们的ClassLoader
不同,但是从ReportFragment
的注入方法:injectIfNeededIn()
和使用方法:get()
来看,这两处代码都是ProcessLifecycleOwnerInitializer
在初始化时注册的Activity
的生命周期监听中回调的。又因为在类A中通过new
关键字创建类B,类B的ClassLoader就是类A的ClassLoader,那么这两处代码中的ReportFragment
的Classloader应该是同一个,为什么会出现ClassLoader不一致的情况呢?
这就要从FragmentActivity
的状态保存说起,来看代码,FragmentActivity#onSaveInstanceState()
中,this.mFragments.saveAllState
会保存Fragment
。
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
this.markFragmentsCreated();
Parcelable p = this.mFragments.saveAllState();
if (p != null) {
outState.putParcelable("android:support:fragments", p);
}
...
}
}