问题一、Settings的主界面是怎么实现的?
Settings.java继承自PreferenceActivity,是Settings的主界面,它通过loadHeadersFromResource函数(api level 11)加载res/xml/settings_headers.xml来构造界面。在settings_headers.xml中声明了要在Settings主界面显示的各个header(如Sound、Display等)。Settings.HeaderAdapter将其中的header分为三类。在Settings.HeaderAdapter中的getView方法中根据header的类型使用不同的布局文件。
static int getHeaderType(Header header) {
return HEADER_TYPE_CATEGORY; //因为没有指明fragment和intent
return HEADER_TYPE_SWITCH; //针对特定的三个header,分别为Wi-Fi、Bluetooth和Mobile data
return HEADER_TYPE_NORMAL;
}
问题二、为什么使用hierarchyviewer时Settings中的很多界面显示的都是SubSettings?
SubSettings.java中的注释很清楚的告诉了我们原因:
原来是因为Settings.java在声明时指定了android:launchMode="singleTask"。
onBuildStartFragmentIntent函数会为我们构造一个显示Fragment的Intent对象(该函数的注释写的非常明白).Settings.java重写了这个函数(注,重写时它调用了super的该方法),在为intent对象setClass时都使用SubSettings.java.(注:在settings_headers.xml指定了intent的header是不会触发onBuildStartFragmentIntent的)
问题三、hierarchyviewer中显示SubSetting时如何确定我进入的是哪个fragment?
例如,当我们点击Display时hierarchyviewer中显示SubSetting。我们通过查找settings_headers就可知道使用的是哪个fragment。
<!-- Display -->
android:id="@+id/display_settings"
android:fragment="com.android.settings.DisplaySettings"
header中使用android:fragment指明使用的fragment。由此可知,Display使用的是com.android.settings.DisplaySettings这个fragment
点击设置界面的header时,会触发Settings中onHeaderClick函数,主要的处理都在其父类PreferenceActivity的onHeaderClick中实现的。如果这个header指定了fragment,在mSinglePane(标识是否为小屏幕设备。如,区分手机还是平板)为true时,会调用startWithFragment方法,在startWithFragment方法中将调用onBuildStartFragmentIntent方法来构造intent对象(重要),最后使用该intent对象启动一个activity来显示fragment。
(Bluetooth同理,只不过启动的Activity变为BluetoothSettingsActivity(继承自Settings,但是没有实现重写任何方法,所以与SubSettings是一样的处理),fragment变为com.android.settings.bluetooth.BluetoothSettings)
执行startActivity后将启动SubSettings.java。即我们将会再一次执行SubSettings和PreferenceActivity的onCreate方法(因为Settings.java的onCreate方法调用了super.onCreate),但是这次并不会进入Settings的主界面,因为我们的使用的intent对象是有很大不同的。这一次onCreate函数(PreferenceActivity)中的initialFragment将被初始化为com.android.settings.DisplaySettings,然后我们将进入switchToHeader,最后switchToHeaderInner会取得FragmentTransaction对象,然后执行了transaction.replace(com.android.internal.R.id.prefs, f).就这样把我们的fragment显示出来了。在onCreate中会对其他view的visibility进行设置,以保证只显示prefs。如,将com.android.internal.R.id.headers的visibility设置为VIEW.GONE.
问题五、Settings.java中getmetaData与getStartingFragmentClass这两个函数是否有点矛盾?
问题六、Settings的shortcut是如何创建的?从shortcut进入Settings的流程是什么?
CreateShortcut中列出了可以创建shortcut的设置项,这些设置项怎样检索出来的?
<category android:name="com.android.settings.SHORTCUT" />
<category android:name="com.android.settings.SHORTCUT" />
回到正题,点击shortcut进入Settings时,传入的Intent对象中包含了目标fragment和目标activity以及其他信息。 PreferenceActivity得到了足够多的信息,因此在onCreate中将依次执行switchToHeader->setSelectedHeader(null)->switchToHeaderInner->transaction.replace(com.android.internal.R.id.prefs, f);
问题七、为什么我从Settings的shortcut进入时,hierarchyviewer显示的就不是SubSettings(如Data usage)?
问题八、Settings.java中很多继承自它的内部类都是空实现,为什么要写这些类?
北方网教育频道 新闻纠错、投诉及爆料热线:022-23601753
