Android O源码Settings之NFC与Tap&pay
Android M和N的Settings应用主界面布局,没有太大的变化,但是在实现方式上已经有些差别。
但是到了O版本,实现方式和N 接近,但是分类各菜单的归类已经有了很大差异。
下面来看看Android O在真机中的表现。
从Settings主界面来看,O不再有device,personal,system等分组了,而每个菜单项即其子菜单项的分组。
那么问题来了,由于项目NFC模块尚未合成,导致NfcAdapter无法获取实例,导致NFC相关的菜单项被隐藏,
那么这些相关项又被挪到了哪里呢?
首先,根据相关类名寻Manifest,得如下信息。
据以往项目N/M中,PaymentSettings即用来管理支付应用的一个菜单菜单都应的界面,那么它依附于谁呢。
据搜索结果可知,其依附于DefaultAppsSettings这个界面中的某个菜单项,其它的类都不是,DefaultPaymentSettingsPreferenceController是用来控制PaymentSettings显示。
再瞅瞅DefaultAppsSettings实现,其布局可查app_default_settings.xml。
getPreferenceScreenResId方法获取到界面布局资源文件,在本Fragment(DefaultAppSettings)创建onCreate时调用。
而getPreferenceControllers方法则在Fragment被附在Activity上时调用,并在DefaultAppSettings的父类DashboardFragment中有个成员用来存储获取到的PreferenceControllers。
@Override
public void onAttach(Context context) {
super.onAttach(context);
mDashboardFeatureProvider =
FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
mProgressiveDisclosureMixin = mDashboardFeatureProvider
.getProgressiveDisclosureMixin(context, this, getArguments());
getLifecycle().addObserver(mProgressiveDisclosureMixin);
List<AbstractPreferenceController> controllers = getPreferenceControllers(context);///
if (controllers == null) {
controllers = new ArrayList<>();
}
mPlaceholderPreferenceController =
new DashboardTilePlaceholderPreferenceController(context);
controllers.add(mPlaceholderPreferenceController);
for (AbstractPreferenceController controller : controllers) {
addPreferenceController(controller);///
}
}
protected void addPreferenceController(AbstractPreferenceController controller) {
mPreferenceControllers.put(controller.getClass(), controller);
}
也就是说,这些controller是在DefaultAppSettings的onCreate()方法之前,已经被map对象持有了。
下面看看打印的大致log。
不管subSettings对应的哪个Fragment,无论是AppAndNotificationDashboardFragment还是DefaultAppSettings,都是集成自DashboardFragment,所有log均加在DashboardFragment,基本每个Fragment的生命周期看它即可,具体到某个Fragment,只需要提供之间的区别点即可,例如:布局文件,类似与Settings Activity的处理方式。
由以上log可知,
onAttach()在onCreate()之前即已被执行,即在onCreate()时已持有布局中各菜单项对应的各controllers对象引用。
由此,Fragment各生命周期中均可根据controller的控制消息来决定显示与否。
下面来看个比较另类的简图。
由中轴线而分,左边为Fragment生命周期中重要的几个方法调用,右边为controller所能提供的信息,Fragment生命周期中合理地使用controller提供的信息来描绘perferenceKey对应的perference行为表现。
最后,强行修改controller中提供的isAvailable(),让显示隐藏的tap & pay菜单,并通过updateState()更新对应的summary,给出一个test 效果。
截图如下:
图中图标和summary为强制更改controller的updateState()方法中进行设置的。