最近要改蓝牙相关的东西,顺道看了看其中的Acitivity,发现有些Activity找不到对应的文件,不像在应用层做的会有自己的XXX.java文件。例如我要修改的ConnectedDeviceDashboardActivity。
先在Settings App的Manifest中搜索它

发现只有这个activity,然后可以看到它是继承于Settings这个activity,然后我又去文件目录中找对应的activity,发现找不到对应的文件,没有办法只有先去看它的父Activity。

发现它也没啥特别的,只好去看看它对应的文件,好在它又对应的java文件,于是就发现它的Activity都是这样创建的。

哇,发现一个我从来没见过的用法,Settings下的大部分Activity都继承于同一个父类,于是只好去看看它的父类,发现终于看到熟悉的Activity了,先看了看onCreate()生命周期,

先从manifest文件中得到额外数据,取得可能存在的要加载的Fragment,但是Settings这个Activity没有对应的meta-Data,所以会返回空,继续往下,


这里做了下是不是从快捷键进入,是不是Settings主界面,mIsShowingDashboard这个参数决定了后面是加载Settings主界面还是其他的Activity,这里当前的Activity就是Settings,所以该值为true,继续往下

这里设置了一下显示导航栏,隐藏原来的标题栏并使其不可点击,差不多Settings的Activity就启动完了。
那么怎么加载的不同界面喃,还记得之前的getMetaData()方法里的mFragmentClass吗,搜索发现只有一处地方使用了getStartingFragmentClass()方法,找它的调用之处,发现和之前对上了;如果返回的fragment不为空,则把Fragment添加到intent中


发现存入Intent中的Fragment的名字马上就取了出来,并且在后面被使用了,

如果savedState不为空,比如旋转屏幕这种情况,那么就不从新加载,

进入launchSettingFragment()方法,可以看到当不是显示主设置界面以及加载的Fragement的名字不为空时,就会调用switchToFragment()方法

进入switchToFragment()方法,经过一些判断Fragment没有问题后,就可以初始化了,调用Fragment的instantiate方法,

这个方法会先去缓存中查找有无该fragment,有则直接加载,没有则会调用newInstance()方法创建一个新的Fragment,之后在这个方法里还会判断args是否为null,不为null则将之前的参数保存到新的fragment中,这也告诉我们在Fragment中存储数据最好使用setArguments()方法传递数据,而不是通过带参数的构造方法,

扩展:
看看onResume()生命周期,

发现只有这么几行代码,进入updateTitlesList()方法,

发现它开启了一个线程调用doUpdateTilesList()方法,进入,

进入该方法发现一长串的setTileEnabled方法,又调用了new ComponentName(),直觉告诉我们终于要找了,进入setTileEnabled(),

先判断是否合法,然后返回,在该文件中搜索setTileEnabled()方法,你会发现只有这么一处,不科学啊,参数对不齐,肯定不是这个方法了,又不可能是实现接口,那就只能是继承了,

然后你就发现它还不在同一个包下,只有跳出工程去看看,找到SettingsDrawerActivity,

搜索setTileEnabled()方法,

这里传入的enabled的值是由!UserManager.isDeviceInDemoMode(this),一般为enabled值为ture,我查看了isDeviceInDemoMode()这个方法,发现它和Demo Mode,演示模式有关,一般没开启演示模式就不会返回true,


今日份就分析到这儿,又学到了好多。
手打不易,给个赞呗(Ubuntu下没表情~_~)
网友评论