Android启动器(Launcher)开发详解
2013-06-07 11:48:15 我来说两句 作者:nexttake
收藏 我要投稿

第1章 Launcher的诞生

1.1 Framework启动Launcher流程


1.2 Launcher自身启动流程
App-Launcher-数据加载和UI绑定
目录 [隐藏]
1 1.Launcher桌面数据和主菜单数据加载流程
1.1 1.1 加载主菜单数据
1.1.1 1.加载调用流程
1.2 1.2 加载桌面数据
1.3 1.3 插入SIM卡时候的数据加载的问题
1.4 1.4 经典Bug
1.4.1 166085

[编辑]1.Launcher桌面数据和主菜单数据加载流程[编辑]1.1 加载主菜单数据PackageManager中加载应用程序数据结构,AppwidgetsManager中加载小部件数据结构,从Favorites数据库中加载桌面数据结构


[编辑]1.加载调用流程LoaderTask一个任务是加载桌面,一个任务是加载抽屉,同步(一个接一个)进行。LauncherModel:waitForIdle()方法用于等待桌面加载完成再加载抽屉。
等待从favorite表中loadAndBindWorkspace的完成,即完成 桌面的数据 从数据库到内存对象的加载,并且已经显示到了桌面Workspace,
然后开始loadAndBindAllApps加载主菜单的数据(PackageManager) ,在launcher-loader 子线程获取数据后通过mHandler.postIdle() mHandler.post()将任务post到主线程任务队列DefferedHandler:mQueue中更新UI。


/** Runs the specified runnable immediately if called from the main thread, otherwise it is
* posted on the main thread handler. */
private void runOnMainThread(Runnable r) {
if (sWorkerThread.getThreadId() == Process.myTid()) {
// If we are on the worker thread, post onto the main handler
mHandler.post(r);
} else {
r.run();
}
}
/** Runs the specified runnable immediately if called from the worker thread, otherwise it is
* posted on the worker thread handler. */
private static void runOnWorkerThread(Runnable r) {
if (sWorkerThread.getThreadId() == Process.myTid()) {
r.run();
} else {
// If we are not on the worker thread, then post to the worker handler
sWorker.post(r);
}
}
当用户点击主菜单按钮的时候,将loadAllAppsByBatch获得的数据与PagedViewIcon绑定。 AppsCustomizePagedView:syncAppsPageItems将ApplicationInfo数组构建每一个 PagedViewIcon并添加到PagedViewCellLayout。


for (int i = startIndex; i < endIndex; ++i) {
ApplicationInfo info = mApps.get(i);
PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate(
R.layout.apps_customize_application, layout, false);
icon.applyFromApplicationInfo(info, true, this);
pagedViewCellLayout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
items.add(info);
images.add(info.iconBitmap);
}
LoaderTask:run()--->LoaderTask:loadAndBindAllApps()--->LoaderTask:loadAllAppsByBatch()--->
Launcher:bindAllApplications()--->AppsCustomizePagedView:setApps()--->AppsCustomizePagedView:invalidateOnDataChange()


在点击“主菜单”按钮之前, AppsCustomizePagedView没有任何 Child.点击之后执行时序如下: AppsCustomizeTabHost.onMeasure(...)--->AppsCustomizePagedView.onMeasure(...)--->AppsCustomizePagedView.onDataReady(...)--->(AppsCustomizePagedView)PagedView.invalidatePageData--->AppsCustomizePagedView:syncPages()

[编辑]1.2 加载桌面数据LauncherModel:startLoader--->LoaderTask:bindWorkspace--->LoaderTask:bindWorkspaceItems--->Launcher:bindItems


[编辑]1.3 插入SIM卡时候的数据加载的问题1.Launcher因为低内存会导致Launcher Activtiy 执行onDestory() onCreate(),会再次执行


startLoader-->loadAndBindWorkSpace---->loadAndBindAllApps

2.Launcher 注册了act=android.intent.action.CONFIGURATION_CHANGED Reload apps on config change. curr_mcc:460 prevmcc:0 当识别SIM 的时候也会执行

startLoader-->loadAndBindWorkSpace---->loadAndBindAllApps
但是这两种情况导致startLoader调用的时候mAllAppsLoaded==false,mWorkspaceLoaded==false 所以其实是在执行如下,不会重新加载数据结构ArrayList<ApplicationInfo>

startLoader-->BindWorkSpace---->onlyBindAllApps

--------------------------------------------------------------------------------

private void loadAndBindAllApps() {
if (DEBUG_LOADERS) {
Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded);
}
if (!mAllAppsLoaded) {
loadAllAppsFromPersistence();
loadAllAppsByBatch();
synchronized (LoaderTask.this) {
if (mStopped) {
return;
}
mAllAppsLoaded = true;
}
} else {
onlyBindAllApps();
}
}

--------------------------------------------------------------------------------
[编辑]1.4 经典Bug[编辑]166085Launcher:onCreate()---new Thread--->startLoader--->读favoriteDB--->post(bindItem)
|
Launcher:onReume()----new Thread--->getMissedCallCount--->post(updateCallLogIcon)------>workspace:updateShortCut()

当来电 启动 InCallScreen 的时候 会执行Launher:onDestory,挂了电话会执行Launcher:onCreate 由于startLoader消耗的时间 要比getMissedCallCount 长,导致post(updateCallLogIcon)先被执行, 可是这个时候桌面的图标没有被bind,导致没有将未接来电的图标进行更新。

第2章 Launcher布局与视图
2.1 hierarchyviewer研究launcher.xml布局

在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率。其中的一款叫Hierachy Viewer的可视化调试工具,可以很方便地在开发者设计,调试和调整界面时,提高用户的开发效率。

第3章 Launcher View拖拽详解

第4章 Launcher AppWiget架构

第5章 桌面缩略图实现

更多相关文章

  1. Android(安卓)Post请求SQL数据库
  2. Android滑动冲突解决方式(下拉刷新上拉加载更多,适配RecyclerVie
  3. android柱状图和饼状图的的实现
  4. Android(安卓)studio 中Activity以及EditText的一些用法和问题
  5. Android系列之SQLite与Android(安卓)Studio的数据交互
  6. Android(安卓)使用Post与Get方法进行表单提交数据
  7. [Android] S​Q​l​i​t​e​数​据​库
  8. Android之旅十三 android中的数据传递方法
  9. 往Android的Application对象里存储数据的陷阱

随机推荐

  1. Android微信端的下拉刷新功能
  2. android 中文api (84) —— TrafficStats
  3. android4.0 开启硬件加速后应用运行出错
  4. Android微信SDK API 调用教程
  5. 阿里巴巴首席战略官:阿里云要当中国Androi
  6. android开发4:布局管理器1(线性布局,相对布
  7. Android滑动的实现
  8. 理解Android进程创建流程
  9. Android 使用ViewPager实现广告条滚动
  10. Android设置Edittext只能输入字母数字弹