第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > android 启动器开发 Android启动器(Launcher)开发详解

android 启动器开发 Android启动器(Launcher)开发详解

时间:2022-02-15 18:15:54

相关推荐

android 启动器开发 Android启动器(Launcher)开发详解

目录

[隐藏]

11.Launcher桌面数据和主菜单数据加载流程

1.11.1 加载主菜单数据

1.1.11.加载调用流程

1.21.2 加载桌面数据

1.31.3 插入SIM卡时候的数据加载的问题

1.41.4 经典Bug

1.4.1166085

[编辑]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

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

[编辑]166085

Launcher: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,导致没有将未接来电的图标进行更新。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。