launcher 启动过程

本文详细解析了Launcher应用程序的启动过程,包括LauncherApplication和Launcher的重要初始化步骤,以及如何加载桌面图标和应用列表。

http://blog.youkuaiyun.com/stonecao/article/details/6536083

一LauncherApplication->onCreate

        --1.//设置最小堆内存4M
        --2.//建立应用图标缓存器
        --3.//建立LauncherModel
        --4.//注册Intent.ACTION_PACKAGE_ADDED,Intent.ACTION_PACKAGE_REMOVED,Intent.ACTION_PACKAGE_CHANGED事件监听器
                        LauncherModel作为广播接收器对上面3中事件进行监听
        --5.//添加对桌面favorites content provider 数据变化监听器
二Launcher->onCreate
        --1.获取LauncherApplication LauncherModel mIconCache等LauncherApplication初始化的对象
        --2.新建拖放控制器new DragController(this)
        --4.//获取桌面组件管理器,启动桌面组件host
                --待深入研究
        --5.//从array.hotseats中加载所有的hotseats(热键 如挂机按钮,google浏览器)
                --待深入研究
        --6.从launcher.preferences加载本地设置
        --7.//设置壁纸尺寸宽度=display.getWidth()* WALLPAPER_SCREENS_SPAN,高度=display.getHeight()
        --8.//加载布局文件
        --9.//初始化所有控件
        --10.//从Bundle savedInstanceState获取桌面持久化数据 设置mRestoring = true;
        --11.如果mRestoring == false,调用LauncherModel加载桌面项 mModel.startLoader(this, true,isLanguageChange);
                --a.LauncherModel.Loader.startLoader() 代码同步处理
                --b.新建LauncherModel.Loader.LoaderThread线程并启动线程(桌面项加载,详细见第三步)
        --12.注册Intent.ACTION_CLOSE_SYSTEM_DIALOGS广播监听
三 桌面项加载 LauncherModel.Loader.LoaderThread.run:新线程执行
        --1.等待主线程运行结束才开始加载
        --2.判断是否先加载桌面;loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;
        --3.loadWorkspaceFirst==true
                --a.loadAndBindWorkspace()
                        --loadWorkspace():从数据库launcher.db中查询中所有桌面项构造对应类型的ItemInfo对象存入
                        mItems,mAppWidgets,mFolders列表。
                        --bindWorkspace():
                                --1.laucher.startBinding(),异步调用,在主线程中handle
                                        //do no things
                                --2.laucher.bindItems(),异步调用,在主线程中handle
                                        --1.根据ItemInfo对象创建桌面图标view对象
                                        --2.获取item.screen, item.cellX, item.cellY, spanX, spanY,
                                                        调用workspace.addInScreen添加到对应桌面的cell
                                                --1.重新设置桌面图标view 的layoutparam(类型为cellLayout.layoutparam)
                                                --2.根据item.screen获取桌面的celllayout对象,也就是workspace下5个用户桌面中的一个
                                                --3.调用celllayout.addview方法把桌面图标view对象添加为celllayout的child,也就是为用户桌面添加一个桌面图标 
                                                --4.桌面图标view对象添加OnLongClickListener=laucher,由laucher负责监听桌面图标view的longclick事件
                                                --5.如果桌面图标是DropTarget对象,拖放控制器mDragController添加该view到拖放目的地列表
                                --3.laucher.bindFolders(),异步调用,在主线程中handle
                                        //launcher.mFolders.putAll(mFolders);
                                --4.laucher.bindAppWidget(),异步调用,在主线程中handle
                                        --1.获取LauncherAppWidgetInfo的appWidgetId
                                        --2.获取AppWidgetProviderInfo appWidgetInfo mAppWidgetManager.getAppWidgetInfo(appWidgetId)
                                        --3.根据appWidgetInfo创建桌面组件的view AppWidgetHostView对象
                                        --4.调用workspace.addInScreen添加到对应桌面的cell                                        
                                --5.laucher.finishBindingItems(),异步调用,在主线程中handle
                                        --mWorkspaceLoading=false      
                --b.loadAndBindAllApps();
                        如果没有加载apps或者改变了语言设置
                        loadAllAppsByBatch();
                                --1.//设置package 查询条件Intent.ACTION_MAIN Intent.CATEGORY_LAUNCHER
                                --2.//清空mAllAppsList mAllAppsList.clear();
                                --3.//packageManager 查询所有应用pakages
                                --4.分批次mAllAppsList.add 应用pakages
                                --5.laucher.bindAllApplications()//异步调用
                                        --mAllAppsGrid.setApps(apps)
                                --6.若分多个批次加载 laucher.bindAppsAdded()//异步调用
                                        --mAllAppsGrid.addApps(apps);
                        否则
                        onlyBindAllApps();
                                --1.mAllAppsList.data.clone();
                                --2.laucher.bindAllApplications()//异步调用
                                        --mAllAppsGrid.setApps(apps)
        --4.loadWorkspaceFirst==false
                --a.loadAndBindAllApps();                        
                --b.loadAndBindWorkspace();
<think> 我们讨论的是Android系统中Launcher启动过程Launcher是Android系统的桌面应用,负责管理应用图标和小部件,并提供用户交互界面。它的启动属于系统启动流程的一部分,通常在SystemServer启动完成后由ActivityManagerService触发。 回答结构: 1. 简述Launcher的作用和重要性。 2. 详细描述Launcher启动的关键步骤,包括触发时机、启动流程等。 3. 可以包含关键代码片段(如AMS中启动Launcher的部分)。 4. 最后提出3-5个相关问题。 注意:末尾必须包含“§§相关问题§§”行,然后紧跟问题列表。 </think> Launcher(桌面)是 Android 系统中用户交互的关键入口,其启动标志着系统完成初始化并进入可用状态。整个启动流程由 ActivityManagerService (AMS) 主导,具体过程如下: ### 启动核心流程 1. **触发时机** 当 SystemServer 完成所有服务初始化后,AMS 会发送 `BOOT_COMPLETED` 广播,并调用 `startHomeActivity()` 方法: ```java // ActivityManagerService.java void startHomeActivity(int userId, String reason) { // 1. 检查当前是否有前台Activity if (hasForegroundActivity()) return; // 2. 解析Launcher的Intent Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); // 3. 启动Launcher进程 mActivityStartController.startHomeActivity(intent, reason, userId); } ``` 2. **进程创建阶段** - AMS 通过 Binder 向 Zygote 发送 `fork()` 请求 - Zygote 复制自身生成 Launcher 进程(通常 PID > 10000) - 继承预加载的 ART 虚拟机状态,跳过 JVM 初始化 3. **组件初始化** Launcher 进程执行关键操作: ```java // LauncherApp.java protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 1. 绑定壁纸服务(WallpaperManagerService) bindWallpaper(); // 2. 加载桌面布局(workspace.xml) inflateWorkspace(); // 3. 扫描应用图标(通过PackageManager) loadAllAppsIcons(); } ``` 4. **界面绘制流程** ```mermaid sequenceDiagram Launcher->>+WMS: 申请创建窗口(ADD_WINDOW) WMS->>+SurfaceFlinger: 分配图形缓冲区(dequeueBuffer) SurfaceFlinger-->>-WMS: 返回Buffer句柄 WMS->>+Launcher: 通知开始绘制(relayoutWindow) Launcher->>+GPU: 渲染图标/小部件(OpenGL/Vulkan) GPU-->>-SurfaceFlinger: 提交合成帧(queueBuffer) ``` ### 性能优化机制 1. **预加载缓存** - SystemUI 进程提前加载 Launcher 资源(图标/布局) - 使用 `SharedMemory` 共享只读内存(节省 30% 启动时间) 2. **阶段化启动** | **阶段** | 执行内容 | 耗时目标 | |------------|--------------------------|----------| | 冷启动 | 进程创建+基础布局 | < 400ms | | 温启动 | 图标加载+动画初始化 | < 200ms | | 热启动 | 恢复前台状态(onResume) | < 50ms | 3. **保活策略** - 进程优先级设为 `PERSISTENT` - 内存不足时最后被回收(oom_adj=0) ### 故障恢复场景 - **崩溃重启**:AMS 检测到 Launcher 进程终止后自动重新启动 - **卡死处理**:Watchdog 每 60 秒检测主线程响应,超时则重启 SystemServer
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值