主入口为com.android.settings.Settings. 这只是一个wrapper的类, 它继承于 SettingsActivity类,并且声明了一堆公有的继承于SettingsActivity的类作为内部类。 例如:
public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
public static class WirelessSettingsActivity extends SettingsActivity { /* empty */ }
public static class SimSettingsActivity extends SettingsActivity { /* empty */ }

所以,来看SettingsActivity。 这个类里面有很多的方法, 我们一开始并不知道哪些是在初始化时有用的。所以先全部打上断点。 然后点击Launcher里面的Settings开始断点调试。 命中的函数断点并不算太多,我们会注意到这个函数: buildDashboardCategories, 在这个函数被调用以后,界面差不多就加载好了。 事实上,这个函数会调用 loadCategoriesFromResource这个函数。而这个函数里面看起来像是在加载XML资源。 现在, 终点大概找到了。 下面再来理清楚它是怎么逐步调用的。 来看命中buildDashboardCategories时候的堆栈。 可以看到, 起源在于DashboardSummary里面的rebuildUI的函数。 而这个函数是由一个handler调用起来的。

 
 
查找这个handler如下:

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REBUILD_UI: {
final Context context = getActivity();
rebuildUI(context);
} break;
}
}
};

这个私有的handler,在当前文件可以找到调用方: sendRebuildUI(),在这里打断点,察看堆栈,会发现它是由DashboardSummary的onResume()方法调用的。 再来看这个类的
定义: DashboardSummary extends Fragment。 是一个Fragment。 所以它是在这个Fragment加载时候触发的。 Fragment的加载,要么是在XML文件里面定义好了,要么是用
代码在运行时加载的。 所以应该去察看SetttingsActivity的UI加载部分,也就是要找setContentView函数。 我们找到了这段代码:

setContentView(mIsShowingDashboard ?
                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);

经过断点调试,可以看到这里调用的是R.layout.settings_main_dashboard。 来看它的布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_content"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="@color/dashboard_background_color"
/>

很简单,只有一个frameLayout, id为main_content, 并不是我们期望的Fragment。 在onCreate里面继续往下找, 或者搜索DashboardSummary(因为在布局里面没有看到
DashboardSummary, 所以必然Activity用代码的方式调用了DashboardSummary), 很容易找到了switchToFragment函数:

调用:
switchToFragment(DashboardSummary.class.getName(), null, false, false,
                        mInitialTitleResId, mInitialTitle, false);

这个函数代码不多, 看起来容易, 里面有几句:

Fragment f = Fragment.instantiate(this, fragmentName, args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_content, f);

看到这里就差不多连起来了。 在SettingsActivity里面的onCreate方法里面, 通过调用这个函数, 把名为main_content的对象替换成了DashboardSummary的实例。 继而激活
了这个fragment的onResume-> rebuildUI() -> SettingsActivity里面的buildDashboardCategories() -> 解析XML文件dashboard_categories.xml, 从而获得
Settings主页该显示哪些内容。 如果有兴趣的可以再仔细看一下这个xml和loadCategoriesFromResource函数,看加载了哪些内容。 我想这里可以分享的经验主要是如何面对一段未知的代码来理清楚它的
逻辑走向。 调用堆栈和Call hierarchy都是很好的辅助工具(Call Hierarchy在Android Studio里面的 Navigate-> Call Hierarchy)

[原创]Android Lollipop (5.0) 原生代码 Settings 首页加载逻辑分析的更多相关文章

  1. Android(Lollipop/5.0) Material Design(二) 入门指南

    Material Design系列 Android(Lollipop/5.0)Material Design(一) 简介 Android(Lollipop/5.0)Material Design(二) ...

  2. Android(Lollipop/5.0) Material Design(四) 创建列表和卡片

    Material Design系列 Android(Lollipop/5.0)Material Design(一) 简单介绍 Android(Lollipop/5.0)Material Design( ...

  3. Android(Lollipop/5.0) Material Design(六) 使用图像

    Material Design列 Android(Lollipop/5.0)Material Design(一) 简单介绍 Android(Lollipop/5.0)Material Design(二 ...

  4. Android(Lollipop/5.0) Material Design(一) 简单介绍

    Material Design系列 Android(Lollipop/5.0)Material Design(一) 简单介绍 Android(Lollipop/5.0)Material Design( ...

  5. Android图片管理组件(双缓存+异步加载)

    转自:http://www.oschina.net/code/snippet_219356_18887?p=3#comments ImageManager2这个类具有异步从网络下载图片,从sd读取本地 ...

  6. 驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址

    驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...

  7. Android UI--自定义ListView(实现下拉刷新+加载更多)

    Android UI--自定义ListView(实现下拉刷新+加载更多) 关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆.不过我就没发现比较实用的,要不就是实现起来太复杂,要不就 ...

  8. android 在自定义的listview(有刷新加载项)列表中,数据过少时不能铺满整个屏幕时,header和footer同时显示问题

    android  在自定义的listview(有刷新加载项)列表中,数据过少时,当刷新时,加载项也会显示,这是很头疼的一个问题,查阅了一些资料,总结了一个比较不错的方法: 原来代码: @Overrid ...

  9. 原生js实现懒加载并节流

    像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费.采用懒加载技术,即用户浏览到哪儿,就加载该处的图片.这样节省网络资源.提升用户体验.减少服务器压力. 方法1: ...

随机推荐

  1. css记录

    padding padding-top是在绿色边框内,从顶部向下移20像素位置,默认padding-top 为0时,红色边框为20像素高,通过padding-top属性,为顶部增加了20像素,这时顶部 ...

  2. MSSQL 死锁查询

    SELECT SYS.DM_EXEC_REQUESTS.SESSION_ID,TEXT AS '执行SQL',CLIENT_NET_ADDRESS AS '请求IP',SYS.DM_EXEC_CONN ...

  3. 《Storm入门》中文版

    本文翻译自<Getting Started With Storm>译者:吴京润    编辑:郭蕾 方腾飞 本书的译文仅限于学习和研究之用,没有原作者和译者的授权不能用于商业用途. 译者序 ...

  4. Android sdk资源包res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)

    (1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x ...

  5. CSS3初学篇章_7(布局/浏览器默认样式重置)

    CSS布局说到布局,就不得不提布局的核心<div>标签,它与其它标签一样,也是一个XHTML所支持的标签,专门用于布局设计的容器标签.在css布局方式中,div 是这种布局方式的核心对象, ...

  6. 201301 JAVA题目0-1级

    描述 编写一个函数,传入一个int型数组,返回该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),能满足以上条件,返回 ...

  7. 遍历ArrayList时同时修改引发的问题

    看见一篇博客,没有写完整,于是增补了一下: 博客原文:http://www.cnblogs.com/alipayhutu/archive/2012/08/11/2634073.html 注:黄色字体为 ...

  8. CentOS下设置默认JDK

    最近在弄Linux,用yum源安装opnjdk-devel版本后,用命令ll /etc/alternatives/java查看,发现指向的是jre目录,而不是jdk,在此设置指向jdk目录. 1. 设 ...

  9. php 删除目录及子文件

    function del_dir($dir) { if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { $str = "rmdir /s/q &q ...

  10. Struts2 OGNL 字符串自定义转化对象细节

    要使用Struts2的自定义对象转化,需要几个要点: 1.要有继承DefaultTypeConverter的实现类,要重写convertValue,并且参数value转化而来的String是Strin ...