Launcher3源码分析 — 数据加载过程

转自:Launcher3源码分析 — 数据加载过程

在一般情况下Launcher3的数据加载过程如下图所示:
这里写图片描述

以上是完整的数据加载过程,但在特殊情况下,加载过程会稍微有些不同,比如all apps页面和workspace页面的加载顺序,是否需要从数据库加载数据(如果数据已加载到内存中就不需要重新加载,只需要执行bind的过程),使用同步还是异步加载等。

我们通过具体代码来看不同情况下的数据加载过程。Launcher3的数据加载从Launcher类的onCreate()方法中开始执行,代码如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
        if (!mRestoring) {
            if (sPausedFromUserAction) {
                // If the user leaves launcher, then we should just load items asynchronously when
                // they return.
                mModel.startLoader(true, -1);
            } else {
                // We only load the page synchronously if the user rotates (or triggers a
                // configuration change) while launcher is in the foreground
                mModel.startLoader(true, mWorkspace.getCurrentPage());
            }
        }
        ......
    }

以上的代码有两种情况,情况一:用户主动离开launcher页面,采用异步加载;情况二:launcher在前台,用户旋转了屏幕,采用同步加载。
两种情况都调用了mModel(LauncherModel类)的startLoader()方法,以下是具体代码:

    public void startLoader(boolean isLaunching, int synchronousBindPage) {
        synchronized (mLock) {
            // Don't bother to start the thread if we know it's not going to do anything
            if (mCallbacks != null && mCallbacks.get() != null) {
                // If there is already one running, tell it to stop.
                // also, don't downgrade isLaunching if we're already running
                isLaunching = isLaunching || stopLoaderLocked();
                mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching);
                if (synchronousBindPage > -1 && mAllAppsLoaded && mWorkspaceLoaded) {
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                } else {
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);
                }
            }
        }
    }

mCallback是Callback接口(用于数据加载完进行回调)的一个弱引用,Launcher类实现了这个接口,并会在初始化的时候传给LauncherModel的mCallback,只有在Launcher的Activity不为null时才进行数据加载,如果没有界面,就没必要执行数据加载了。
每次开始加载数据时都会new一个LoaderTask(继承Runnable接口),负责具体的数据加载工作,如果已经有个LoaderTask在执行,会在new之前stop掉。接下来就判断传入的synchronousBindPage的值来选择不同的加载过程。
(sWorkerThread是HandlerThread类的引用,可以返回一个looper对象,sWorker是Handler类的引用,该Handler使用sWorkerThread的looper进行实例化,这样通过调用sWorker.post(Runnable r)就可以在worker thread中执行r的run()方法,LoaderTask继承自Runnable)

接下来看两种情况下数据的加载过程,首先看synchronousBindPage == -1的情况,通过调用sWorker.post(mLoaderTask)会执行mLoaderTask的run()方法。

        public void run() {
            ......
            keep_running: {
                ......
                // first step
                isUpgrade = loadAndBindWorkspace();
                ......
                if (mStopped) {
                    break keep_running;
                }
                ......

                // second step
                loadAndBindAllApps();
                ......
            }
        }

主要进行了两步操作,loadAndBIndWorkspace()负责加载和绑定workspace的数据,loadAndBindAllApps()负责加载和绑定所有应用界面的数据。

第二种情况:synchronousBindPage != -1并且数据已经加载到内存中了,屏幕旋转时进入这种情况,此时执行的是LoaderTask.runBindSynchronousPage(synchronousBindPage); 此方法只进行数据的绑定,并且在当前页面下使用的是同步的方式。

        void runBindSynchronousPage(int synchronousBindPage) {
            bindWorkspace(synchronousBindPage, false);
            onlyBindAllApps();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值