在数据从数据库加载到内存之后,接下来的工作就是把这些数据与launcher的UI视图绑定。绑定的过程在LauncherModel.bindWorkspace()方法中完成,在这个方法中会调用回调接口Callback里相应的回调方法。
Callback接口的定义如下:
public interface Callbacks {
public boolean setLoadOnResume();
public int getCurrentWorkspaceScreen();
public void startBinding();
public void bindItems(ArrayList shortcuts, int start, int end,
boolean forceAnimateIcons);
public void bindScreens(ArrayList orderedScreenIds);
public void bindAddScreens(ArrayList orderedScreenIds);
public void bindFolders(HashMap folders);
public void finishBindingItems(boolean upgradePath);
public void bindAppWidget(LauncherAppWidgetInfo info);
public void bindAllApplications(ArrayList apps);
public void bindAppsAdded(ArrayList newScreens,
ArrayList addNotAnimated,
ArrayList addAnimated,
ArrayList addedApps);
public void bindAppsUpdated(ArrayList apps);
public void bindComponentsRemoved(ArrayList packageNames,
ArrayList appInfos,
boolean matchPackageNamesOnly);
public void bindPackagesUpdated(ArrayList
通过方法名我们大概可以猜到每个回调方法的作用,因为Launcher类(Main Activity)实现了该接口,并作为参数传递给了LauncherModel的mCallback,所以bindWorkspace的过程就是通过回调,一步步地通知Launcher类进行相应界面和相应数据的绑定。
bindWorkspace的过程如下:
1.将items分为current和other
ArrayList currentWorkspaceItems = new ArrayList();
ArrayList otherWorkspaceItems = new ArrayList();
ArrayList currentAppWidgets =
new ArrayList();
ArrayList otherAppWidgets =
new ArrayList();
HashMap currentFolders = new HashMap();
HashMap otherFolders = new HashMap();
// Separate the items that are on the current screen, and all the other remaining items
filterCurrentWorkspaceItems(currentScreen, workspaceItems, currentWorkspaceItems,
otherWorkspaceItems);
filterCurrentAppWidgets(currentScreen, appWidgets, currentAppWidgets,
otherAppWidgets);
filterCurrentFolders(currentScreen, itemsIdMap, folders, currentFolders,
otherFolders);
sortWorkspaceItemsSpatially(currentWorkspaceItems);
sortWorkspaceItemsSpatially(otherWorkspaceItems);
先绑定当前页面的数据,再绑定其他页面,从而提供更好的用户体验。
// Tell the workspace that we're about to start binding items
r = new Runnable() {
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.startBinding();
}
}
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
完成绑定前的初始化工作。
3.调用bindScreens()
final Runnable r = new Runnable() {
@Override
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.bindScreens(orderedScreens);
}
}
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
完成screen的初始化。
4.加载当前页面的item
bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets,
currentFolders, null);
bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders,
(isLoadingSynchronously ? mDeferredBindRunnables : null));
// Tell the workspace that we're done binding items
r = new Runnable() {
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
callbacks.finishBindingItems(isUpgradePath);
}
mIsLoadingAndBindingWorkspace = false;
}
};
runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE);
以上是Workspace数据绑定的步骤,Launcher类通过回调在每个步骤中完成相应的UI渲染工作。