您的位置:首页 > 其它

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

2014-03-05 10:41 597 查看
在一般情况下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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: