Android 5.0 Settings源码简要分析
概述:
先声明:本人工作快两年了,仍是菜鸟级别的,惭愧啊!以前遇到好多知识点都没有记录下来,感觉挺可惜的,现在有机会接触Android 源码。我们一个Android组的搞Setting,我觉得是得写得东西,毕竟才接触,现在只能看一段时间代码,就先记录下一些收获吧,说多了就是泪~本文主要针对L平台上Settings模块正常启动流程做一个简要分析,并试着分析一下Settings下面某选项的实现。
Setting 简介
在之前的KK平台上Settings模块的第一个Activity名字为Settings,其继承的是PreferenceActivity,设置的每一个选项都是对应的一个Header对象,并且Header对象允许显示switch控件,button控件,checkbox控件等。如下图1.1,WLAN和蓝牙上使用到了switch开关。但在L上面,WLAN和蓝牙的这两个开关已经去掉了,如图1.2,在Settings模块的首个页面似乎就只是一个普通的Listview,那它用的还是不是Header呢?或者说取而代之的是什么呢?继续往下看吧~
图片-1.1
图片-1.2
L Settings 模块首界面初始化流程
L Settings模块首界面为Settings,继承自SettingsActivity,SettingsActivity继承自Activity。
首先看一下Settings.java代码可以发现它没有重写任何SettingsActiviy的方法,也没有增加任何自己的方法,唯独增加了许多静态内部类,如:
/**
* Top-level Settings activity
*/
public class Settings extends SettingsActivity {
/*
* Settings subclasses for launching independently.
*/
public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
public static class WirelessSettingsActivity extends SettingsActivity { /* empty */ }
public static class SimSettingsActivity extends SettingsActivity { /* empty */ }
public static class TetherSettingsActivity extends SettingsActivity { /* empty */ }
public static class VpnSettingsActivity extends SettingsActivity { /* empty */ }
public static class DateTimeSettingsActivity extends SettingsActivity { /* empty */ }
public static class StorageSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiSettingsActivity extends SettingsActivity { /* empty */ }
public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ }
public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ }
public static class KeyboardLayoutPickerActivity extends SettingsActivity { /* empty */ }
public static class InputMethodAndSubtypeEnablerActivity extends SettingsActivity { /* empty */ }
public static class VoiceInputSettingsActivity extends SettingsActivity { /* empty */ }
public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocalePickerActivity extends SettingsActivity { /* empty */ }
public static class UserDictionarySettingsActivity extends SettingsActivity { /* empty */ }
public static class HomeSettingsActivity extends SettingsActivity { /* empty */ }
...
}
看注释可以知道,这些子类是为了启动特定独立的Settings选项而创建的,例如在某个应用里需要设置无线那么只需要启动 WirelessSettingsActivity 就可以了。
所以Settings模块的启动流程直接看SettingsActiviy就行了。
1. SettingsActivity.onCreate方法
onCreate方法是Activity的生命周期第一步,看看 SettingsActivity在这里都做了些什么?
// Should happen before any call to getIntent()
getMetaData();
这个方法用来获得Activity的额外数据mFragmentClass,如果可以获得这个数据,那么下面会去显示mFragmentClass对应的Activity。直接启动Settings模块不会获得这个数据。
mIsShowingDashboard = className.equals(Settings.class.getName());
这一步很重要,因为我们是从Settings这个Activity过来的,所以这里的 mIsShowingDashboard 为 true 。
// This is a "Sub Settings" when:
// - this is a real SubSettings
// - or :settings:show_fragment_as_subsetting is passed to the Intent
final boolean isSubSettings = className.equals(SubSettings.class.getName()) ||
intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
这个判断很重要但很明显这时isSubSettings的值是fasle,暂时忽略。
setContentView(mIsShowingDashboard ?
R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
前面知道这里的 mIsShowingDashboard为true,所以这里使用的布局文件为R.layout.settings_main_dashboard。settings_main_dashboard.xml文件如下:
<framelayout android:background="@color/dashboard_background_color" android:id="@+id/main_content" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"></framelayout>
由于mIsShowingDashboard为true,直接走到下面这段
else {
// No UP affordance if we are displaying the main Dashboard
mDisplayHomeAsUpEnabled = false;
// Show Search affordance
mDisplaySearch = true;
mInitialTitleResId = R.string.dashboard_title;
switchToFragment(DashboardSummary.class.getName(), null, false, false,
mInitialTitleResId, mInitialTitle, false);
}
这里看到switchToFragment这个方法,可以知道这里是要切换DashboardSummary这个Fragment.
接下来就看看DashboardSummary是个什么玩意?
dashboard中文意思是仪表盘,这里是指DashboardSummary就是用来显示Settings所有选项的。
在DashboardSummary的onCreateView里加载了这个布局文件R.layout.dashboard
<code class=" hljs perl"><scrollview xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/dashboard" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbarstyle="outsideOverlay" android:cliptopadding="false"> <linearlayout android:id="@+id/dashboard_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:paddingstart="@dimen/dashboard_padding_start" android:paddingend="@dimen/dashboard_padding_end" android:paddingtop="@dimen/dashboard_padding_top" android:paddingbottom="@dimen/dashboard_padding_bottom" android:orientation="vertical"> </linearlayout></scrollview></code>
看了上面的布局文件可以知道Settings的选项视图应该就是显示在dashboard_container中了。
DashboardSummary走完onCreateView方法后会走onResume,然后一路下来又会调到SettingsActivity的
loadCategoriesFromResource(R.xml.dashboard_categories, categories);
这一步是通过 R.xml.dashboard_categories来加载categories,这里的categorys为ArrayList mCategories。接着来看看dashboard_categories.xml这个文件吧
您可能想查找下面的文章: