4.0.x Launcher启动过程
在Android中AndroidManifest.xml文件具体的描述了该应用的配置信息、全局属性,在启动应用时系统肯定是先读取该文件进行解析,查找程序的入口。一直以为android程序的入口是配置文件中指定的Activity:<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
,看了AndroidManifest.xml,发现里面实现了xml树根节点是Application类,application是直接配置应用的图标和应用名的。android程序的真正入口是Application类的onCreate方法。Application就是Activity,Service之类的组件上下文描述只不过大多数开发者无需重写该类。android.app.Application类包含了4个公有的方法
void onConfigurationChanged(Configuration newConfig)
void onCreate() //这里才是真正的入口点。
void onLowMemory()
void onTerminate()
使用application需要两个步骤:1.继承重写Application类相关方法2.在配置文件中配置。继承Application类来实现应用程序级的全局变量,这种全局变量方法相对静态类更有保障,直到应用的所有Activity全部被destory掉之后才会被释放掉。
Launcher 的入口是LauncherApplication,AndroidManifest.xml中配置的属性:
android:name="com.android.launcher2.LauncherApplication" -----类名
android:label="@string/application_name"---------应用名称
android:icon="@drawable/ic_launcher_home"----------应用程序管理器启动时看到的图标
android:hardwareAccelerated="@bool/config_hardwareAccelerated" ------------是否使用硬件加速,提高应用运行速度
android:largeHeap="@bool/config_largeHeap" ----------设定launcher运行时最小堆内存,避免内存out of memory错误的出现。
一、LauncherApplication----onCreate 应用入口
1)获取屏幕的显示尺寸、密度全局变量。
2)建立应用图标缓存器;创建LauncherModel 对象,在launcher数据变更时操作数据库。
3)注册(Intent.ACTION_PACKAGE_ADDED Intent.ACTION_PACKAGE_REMOVED Intent.ACTION_PACKAGE_CHANGED)应用添加、删除、改变监听;LauncherModel提供接收器对上面3中事件进行监听。
4)注册本地化配置变化监听,搜寻相关变化监听,外部存储上的应用变化监听。接收器同上
5)注册对桌面favorites content provider 数据变化监听器,触发后执行onChang方法。
二、Launcher Activity:实现了点击、长按、触屏、LauncherModel,AllAppViews接口。
Launcher---onCreate,执行完Application初始化配置后进入该方法。
1)获取LauncherApplication初始化全局变量、对象。创建DragController拖放控制对象、AppWidgetManager appwidget管理对象AppWidgetHost appwidget变化监听启动
2)checkForLocaleChange();检查本地化配置
setContentView(R.layout.launcher); 加载布局文件
setupViews(); 初始化空间,包括各种拖放相关的监听事件,Hotseat电话、消息快捷键初始化
showFirstRunWorkspaceCling(); 是否需要显示使用向导
registerContentObservers(); 注册appwidget改变监听 LauncherProvider.CONTENT_APPWIDGET_RESET_URI
lockAllApps(); //nothing to do
3)从Bundle savedInstanceState获取桌面持久化数据restoreState(mSavedState)
更加State ,显示APPS 或workspage页面。
4)mRestoring false,调用LauncherModel ----startLoader(this, true);启动LoaderTask线程开始装载数据(同步处理过程)。
1.优先载入那个页面loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;
2.loadWorkspaceFirst == true. 载入workspace loadAndBindWorkspace()--->
loadWorkspace();从数据库launcher.db中查询中所有桌面项构造对应类型的ItemInfo对象存入 ShortcutInfo,LauncherAppWidgetInfo,FolderInfo列表。
--->// Bind the workspace bindWorkspace()
--->callbacks.startBinding();launcher中回调,清除workspace bind初始化
--->回调callbacks.bindItems(workspaceItems, start, start+chunkSize);根据数据库获取的workspaceItems 列表添加appwidget shorcut类型item.异步调用,在主线程中handler
--->callbacks.bindFolders(folders);添加folders 异步调用,在主线程中handler
--->callbacks.bindAppWidget(widget);添加widget 异步调用,在主线程中handler
三次回调中workspace.addInScreen 传入item添加到对应workspace screen
3.loadWorkspaceFirst == false. loadAndBindAllApps()载入apps 列表。
mAllAppsLoaded ==false,launcher启动后第一次载入。
--->loadAllAppsByBatch()
launcher.bindAllApplications() 异步调用,mAppsCustomizeContent.setApps(apps);
分多个批次加载 launcher.bindAppsAdded() 主线程Handler 调用。 mAppsCustomizeContent.setApps(apps);
mAllAppsLoaded ==true,onlyBindAllApps() 可能由于本地化改变
--->callbacks.bindAllApplications(list)主线程Handler 调用
4.loadWorkspaceFirst == true 装载数据顺序
(1)loadAndBindAllApps();
(2)loadAndBindWorkspace();
三、Launcher.onCreate 后半部分
注册Intent.ACTION_CLOSE_SYSTEM_DIALOGS广播监听
updateAppMarketIcon() 检查是否安装 android market
初始化GlobalSearch。SearchDropTargetBar。
-------------------------------------------------------------------
重要方法LauncherModel.loadWorkspace(); workspace.addInScreen;