Android 4.0 Launcher2源码分析——启动过程分析
Android的应用程序的入口定义在AndroidManifest.xml文件中可以找出:
[html]
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher">
<original-package android:name="com.android.launcher2" />
...
<application
android:name="com.android.launcher2.LauncherApplication"
...
>
<activity
android:name="com.android.launcher2.Launcher"
...
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
...
</application>
</manifest>
从中我们可以知道启动过程需要先后初始化LauncherApplication和Launcher的对象。更加简洁的说,启动过程可以分成两步,第一步在
LauncherApplication.onCreate()方法中,第二部在Launcher.onCreate()方法中。
先看第一步,代码片段如下:
[java]
public void onCreate() {
super.onCreate();
// 在创建icon cache之前,我们需要判断屏幕的大小和屏幕的像素密度,以便创建合适大小的icon
final int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
sScreenDensity = getResources().getDisplayMetrics().density;
mIconCache = new IconCache(this);
mModel = new LauncherModel(this, mIconCache);
// 注册广播接收器
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
......
registerReceiver(mModel, filter);
//注册ContentObserver,监听LauncherSettings.Favorites.CONTENT_URI数据的变化
ContentResolver resolver = getContentResolver();
resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true,
mFavoritesObserver);
}
LauncherApplication是Application的子类,是整个程序的入口。因此,一些全局信息的初始化和保存工作就放到这里执行。包括屏幕大小,像素密度信息的获取,以及
BroadcastReceiver和ContentObserver的注册都在整个程序的开始就完成。LauncherApplication的工作结束之后,下面就开始初始化Launcher了。Launcher是一个Activity,
而Activity的生命周期中,有几个重要的回调方法,而onCreate()方法是最先被执行的用于进行初始化操作的。那下面就来看看Launcher.onCreate()中具体做了哪些操作:
[java]
protected void onCreate(Bundle savedInstanceState) {
...
mModel = app.setLauncher(this);
mIconCache = app.getIconCache();
...
mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
mAppWidgetHost.startListening();
...
//检查本地保存的配置是否需要更新
checkForLocaleChange();
setContentView(R.layout.launcher);
//对UI控件进行初始化和配置
setupViews();
//向用户展示指导的页面
showFirstRunWorkspaceCling();
registerContentObservers();
...
if (!mRestoring) {
//为Launcher加载数据
mModel.startLoader(this, true);
}
...
}
可以通过时序图,直观的认识下,onCreate()中主要进行了哪些操作:
可以将Launcher.onCreate()所执行的操作大概分为七步:
1、LauncherAppliaction.setLauncher()。
2、AppWidgetHost.startListening(),对widget事件进行监听
3、checkForLocaleChange(),检查更新本地保存的配置文件
4、setupViews(),配置UI控件
5、showFirstRunWorkspaceCling(),第一次启动时显示的指导画面
6、registerContentObservers(),设置内容易做图
7、LauncherModel.startLoader(),为Launcher加载Workspace和AllApps中的内容
那么,下面就一步一步的顺着执行的过程来看Launcher启动过程中都做了些什么。
Step1:LauncherApplication.setLauncher()
调用LauncherAppliction对象的setLauncher()方法,得到一个LauncherModel对象的引用,setLauncher内容如下:
[java]
LauncherModel setLauncher(Launcher launcher) {
mModel.initialize(launcher);
return mModel;
}
在setLauncher中继续执行了mModel对象的initialize方法,在initialize中只有小段代码:
[java]
public void initialize(Callbacks callbacks) {
synchronized (mLock) {
mCallbacks = new WeakReference<Callbacks>(callbacks);
}
}
由于Launcher实现了Callback接口。在mModel中,将传入的Launcher对象向下转型为Callback赋值给mCallbacks变量。并在LauncherModel中获得了一个Callbacks的软引
用通过这一过程,将Launcher对象作为Callback与mModel进行绑定,当mModel后续进行操作时,Launcher可以通过回调得到结果。
Step2:mAppWidgetHost.startListening()
LauncherAppWidgetHost继承自AppWidgetHost,它的作用就是帮助Launcher管理AppWidget,并且能够捕获长按事件,使得应用可以正常的删除、添加
AppWidget。通过调用mAppWidgetHost.startListening()方法,开启监听。
Step3:checkForLocaleChange()
接下来执行checkForLocaleChange(),方法内容如下:
[java]
private void checkForLocaleChange() { 补充:移动开发 , Android ,