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()

更加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() 异步调用,.setApps(apps);

分多个批次加载 launcher.bindAppsAdded() 主线程Handler 调用。 .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;

posted @ 2012-05-02 10:08  Colin Xie  阅读(844)  评论(0编辑  收藏  举报