Launcher3源碼分析 — 將Workspace的數據與界面綁定

在數據從數據庫加載到內存之後,接下來的工作就是把這些數據與launcher的UI視圖綁定。綁定的過程在LauncherModel.bindWorkspace()方法中完成,在這個方法中會調用回調接口Callback裏相應的回調方法。


Callback接口的定義如下:

public interface Callbacks {
        public boolean setLoadOnResume();
        public int getCurrentWorkspaceScreen();
        public void startBinding();
        public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end,
                              boolean forceAnimateIcons);
        public void bindScreens(ArrayList<Long> orderedScreenIds);
        public void bindAddScreens(ArrayList<Long> orderedScreenIds);
        public void bindFolders(HashMap<Long,FolderInfo> folders);
        public void finishBindingItems(boolean upgradePath);
        public void bindAppWidget(LauncherAppWidgetInfo info);
        public void bindAllApplications(ArrayList<AppInfo> apps);
        public void bindAppsAdded(ArrayList<Long> newScreens,
                                  ArrayList<ItemInfo> addNotAnimated,
                                  ArrayList<ItemInfo> addAnimated,
                                  ArrayList<AppInfo> addedApps);
        public void bindAppsUpdated(ArrayList<AppInfo> apps);
        public void bindComponentsRemoved(ArrayList<String> packageNames,
                        ArrayList<AppInfo> appInfos,
                        boolean matchPackageNamesOnly);
        public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
        public void bindSearchablesChanged();
        public boolean isAllAppsButtonRank(int rank);
        public void onPageBoundSynchronously(int page);
        public void dumpLogsToLocalData();
    }

通過方法名我們大概可以猜到每個回調方法的作用,因爲Launcher類(Main Activity)實現了該接口,並作爲參數傳遞給了LauncherModel的mCallback,所以bindWorkspace的過程就是通過回調,一步步地通知Launcher類進行相應界面和相應數據的綁定。


bindWorkspace的過程如下:




1.將items分爲current和other

	ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>();
	ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>();
	ArrayList<LauncherAppWidgetInfo> currentAppWidgets =
	    new ArrayList<LauncherAppWidgetInfo>();
	ArrayList<LauncherAppWidgetInfo> otherAppWidgets =
	    new ArrayList<LauncherAppWidgetInfo>();
	HashMap<Long, FolderInfo> currentFolders = new HashMap<Long, FolderInfo>();
	HashMap<Long, FolderInfo> otherFolders = new HashMap<Long, FolderInfo>();

	// 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);

先綁定當前頁面的數據,再綁定其他頁面,從而提供更好的用戶體驗。


2.調用startBinding()

    // 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);


5.加載其他頁面的item

bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders,
                    (isLoadingSynchronously ? mDeferredBindRunnables : null));


6.調用finishBindingItems()
    // 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渲染工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章