主入口为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. sphinx通过增量索引实现近实时更新

    一.sphinx增量索引实现近实时更新设置 数据库中的已有数据很大,又不断有新数据加入到数据库中,也希望能够检索到.全部重新建立索引很消耗资源,因为我们需要更新的数据相比较而言很少. 例如.原来的数据 ...

  2. java位操作总结

    在计算机中所有数据都是以二进制的形式储存的. 位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快. 方便演示,首先写个二进制打印方法: private static void ...

  3. EasyUI 页面分页

    DAO package com.hanqi.dao; import java.util.ArrayList; import java.util.List; import org.hibernate.S ...

  4. ZK 页面间参数传递

    1.execution.sendRedirect(url) 当使用方法execution.sendRedirect(url)进行页面跳转时,在url中添加参数:url?test=5: 跳转页面获取参数 ...

  5. [转载]C++堆栈的入门学习

    申明:   转自    http://www.cnblogs.com/pengshao/archive/2011/12/26/2301461.html 头文件stackDemo.h #pragma o ...

  6. 利用activeX控件在网页里自动登录WIN2003远程桌面并实时控制

    首先要自己配置并打开受控端的WEB远程桌面服务,这个在“添加/删除windows组件”里有,我只在windows 2003 server里试过,没试过XP.下面我们在客户端安装微软提供的远程桌面客户端 ...

  7. IOS网络第五天 AFN-03-监控网络状态

    ******* #import "HMViewController.h" #import "AFNetworking.h" @interface HMViewC ...

  8. hihoCoder 1185 连通性·三(Tarjan缩点+暴力DFS)

    #1185 : 连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出 ...

  9. 关于BeanUiles.copyPropertis()的用法

    最近的项目遇到BeanUiles.copyPropertis(),大大的简化了代码量.用hibernate从数据库中映射的实体类,与pojo对象进行转换,传统做法 Object obj = baseD ...

  10. Apache服务器性能监控

    Apache服务器性能监控 1.使用自带mod_status模块监控 1)加载mod_status.so 模块 在httpd.conf中打开LoadModule status_module modul ...