【源码剖析】Launcher 8.0 源码 (13) --- Launcher 启动流程 第六步之LauncherModel的布局操作(一) 整体概述

之前我们讲了初始化对象,根据硬件参数来获取布局,获取数据参数,所有的都准备好以后,就将进行数据的加载与绑定,本篇文章就来讲讲Launcher 启动流程 第六步之LauncherModel的布局操作。

这一步在Launcher的oncreate启动流程是最关键的一步。这一部分的代码是:

 if (!mModel.startLoader(currentScreen)) {
            // If we are not binding synchronously, show a fade in animation when
            // the first page bind completes.
            mDragLayer.setAlpha(0);
        } else {
            mWorkspace.setCurrentPage(currentScreen);
            setWorkspaceLoading(true);
        }

这里稍微解释一下,mModel.startLoader(currentScreen),让LauncherModel开始读取应用,包括桌面的布局和allApp的所有应用,将所有应用和图标放到之前我们规划好的几行几列的格子里面,返回false表示读取失败,这时会走mDragLayer.setAlpha(0);,也就是Launcher的mDragLayer不显示,也就是桌面时空白的。如果读取成功就开始加载。

mModel.startLoader(currentScreen)

我们从mModel.startLoader(currentScreen)源码开始分析

 public boolean startLoader(int synchronousBindPage) {
        // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
        1.InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);
        synchronized (mLock) {
            // Don't bother to start the thread if we know it's not going to do anything
         2.   if (mCallbacks != null && mCallbacks.get() != null) {
                final Callbacks oldCallbacks = mCallbacks.get();
                mUiExecutor.execute(new Runnable() {
                            public void run() {
                                oldCallbacks.clearPendingBinds();
                            }
                        });
         3.      stopLoader();
         4.      LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,
                        mBgAllAppsList, synchronousBindPage, mCallbacks);
         5.       if (mModelLoaded && !mIsLoaderTaskRunning) {
                    loaderResults.bindWorkspace();
                    loaderResults.bindAllApps();
                    loaderResults.bindDeepShortcuts();
                    loaderResults.bindWidgets();
                    return true;
                } else {
          6.          startLoaderForResults(loaderResults);
                }
            }
        }
        return false;
    }

我把代码分为了6部分,一一进行分析它的作用:

1.在加载之前先开启初始化队列,它会在绑定结束后disabled关掉。

2.判断绑定回调的Callbacks对象是否存在,如果存在就清理掉所有的绑定回调,方便下面重新绑定数据,此处的oldCallbacks.clearPendingBinds();调用的是Launcher里面的clearPendingBinds。

  1. stopLoader(); 如果此时已经有一个Task正在运行,就让它停止掉。

4.创建oaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,
mBgAllAppsList, synchronousBindPage, mCallbacks);创建loaderResults,此类是LauncherModel的辅助类,所有的绑定操作都在此类中完成。

5.判断当前模型数据是否有效以及LoaderTask是否在运行,条件成立的话就直接进行绑定,如果模型数据无效,以及LoaderTask正在运行,那么就调用startLoaderForResults(loaderResults);

6.调用startLoaderForResults(loaderResults);,进行数据的加载和绑定

startLoaderForResults(loaderResults);

在这个方法中,一进来就调用了 stopLoader();,也就是在正式加载之前,再一次去确认停止多有正在运行的task,然后创建新的LoaderTask(线程),所以在调用runOnWorkerThread(mLoaderTask);中的run方法时,其实是调用的LoaderTask的run方法。

public void startLoaderForResults(LoaderResults results) {
        synchronized (mLock) {
            stopLoader();
            mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, results);
            runOnWorkerThread(mLoaderTask);
        }
    }

在LoaderTask的run方法中主要调用了几个重要的方法,加载数据和绑定的方法。

  • 加载和绑定Workspace
    loadWorkspace();
    mResults.bindWorkspace();
    waitForIdle();
  • 加载和绑定AllApps
    loadAllApps();
    mResults.bindAllApps()
    waitForIdle();
  • 加载和绑定小部件
    loadDeepShortcuts();
    mResults.bindDeepShortcuts();
    waitForIdle();
  • 加载和绑定widget
    mBgDataModel.widgetsModel.update(mApp, null);
    mResults.bindWidgets();

接下来会进行详细讲解数据的加载和绑定,这一部分是最重要的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,042评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,490评论 18 139
  • 第009篇:什么是禅定?禅定有什么用?X 第一节:什么是禅定? “禅”是梵文dhyana的发音,读作“禅”。可翻译...
    觉慧了悟阅读 1,144评论 1 4
  • 001 生活 其实就像这杯苦咖啡,难过时,你会感觉涩涩的。开心时,你会觉得再苦也是甜。生活中本来有苦有乐有声有色。...
    青果果说阅读 187评论 0 1
  • “赞” 是一个虚荣肤浅的按钮,区块链将它替换为“付款”,价值则更少泡沫和欺骗。 这是行为和表演的区别,是真实和廉价...
    咸叔说阅读 411评论 3 4