主入口为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. 移动端/H5关于cursor:pointer导致的问题

    cursor属性规定要显示的光标的类型(形状),该属性定义了鼠标指针放在一个元素边界范围内时所用的光标形状(不过 CSS2.1 没有定义由哪个边界确定这个范围). 不过,这个属性用在PC端没有任何问题 ...

  2. 【Alpha】Daily Scrum Meeting总结

    一.项目预期计划和现实进展 项目预期计划 现实进展 登陆 完成 使用菜单 完成 查看自己的信息 完成(额外完成可修改) 完成能用的界面 完成(额外美化) 可以导入导出表格 导入表格完成,导出未完成 教 ...

  3. STL学习之vector

    vector是一个线性顺序结构.相当于数组,但其大小可以不预先指定,并且自动扩展.它可以像指针一样被操作,由于它的特性我们完全可以将vector看做动态数组. 特点: 1.指定一块如同数组一样的连续存 ...

  4. java和js根据一个或者多个空格截取字符串

    java: String str = "张三 fw1234"; String s[] = str.split("\\s+"); js: var str=&quo ...

  5. Python爬虫:Xpath语法笔记

    一.选取节点 常用的路劲表达式: 表达式 描述 实例   nodename 选取nodename节点的所有子节点 xpath(‘//div’) 选取了div节点的所有子节点 / 从根节点选取 xpat ...

  6. 树莓派+移动硬盘搭建NAS服务器

    由于树莓派的USB接口不足以给移动硬盘供电,因此需要另外给移动硬盘提供电源. 显示当前已有的存储设备 # fdisk -l Disk /dev/mmcblk0: 7876 MB, 7876902912 ...

  7. python类型转换

    1.数字转字符串 str(42) == "42" 2.字符串转数字 int("42") == 42 3.字符转ascii码 ord("a") ...

  8. Xshell远程连接工具

    下载地址:http://rj.baidu.com/soft/detail/15201.html?ald Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft ...

  9. C语言语法分析器

    #include <stdio.h> #include <string.h> ], token[]; char ch; int syn,p,m,n,sum; ]= {" ...

  10. Linux_函数使用手册(中、英),确实不错

    http://files.cnblogs.com/files/findumars/Linux_functions_ch_en.rar