Launcher2分析-加载Workspace数据和绑定

本文深入探讨了Launcher2的数据加载过程,包括从default_workspace.xml填充数据库、查询favorite表并创建ItemInfo对象。同时,分析了数据绑定阶段,详细阐述了ItemInfo如何根据container属性分类存储,以及ShortcutInfo、FolderInfo和LauncherAppWidgetInfo的构建。此外,还介绍了AppWidgetInfo的构建以及Widget的绑定方法。
摘要由CSDN通过智能技术生成

通过调用LoaderTask#startLoader()数据加载和绑定,该方法在Launcher#oncreate()中被调用:

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());
            }

其中第二个参数不为-1时,是同步加载,只有桌面正在显示且屏幕发生旋转时才会同步加载。

看startLoader()这个方法源码:

public void startLoader(boolean isLaunching, int synchronousBindPage) {
        synchronized (mLock) {
            if (DEBUG_LOADERS) {
                Log.d(TAG, "startLoader isLaunching=" + isLaunching);
            }

            // Clear any deferred bind-runnables from the synchronized load process
            // We must do this before any loading/binding is scheduled below.
            mDeferredBindRunnables.clear();

            // 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, isLaunching);
                if (synchronousBindPage > -1 && mAllAppsLoaded && mWorkspaceLoaded) {
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);//同步加载时调用runBindSynchronousPage,而不是run()
                } else {
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);//异步加载,在给线程池运行LoaderTask的run()
                 }
            }
        }
    }


下面来分析异步加载时的数据加载和绑定过程。






数据加载

LauncherModel$LoaderTask#run()

public void run() {
            synchronized (mLock) {
                mIsLoaderTaskRunning = true;
            }

            keep_running: {//一直循环运行
                // Elevate priority when Home launches for the first time to avoid
                // starving at boot time. Staring at a blank home is not cool.
               //... ...

                // First step. Load workspace first, this is necessary since adding of apps from
                // managed profile in all apps is deferred until onResume. See http://b/17336902.
                if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
                loadAndBindWorkspace();//加载桌面数据和绑定

                if (mStopped) {
                    break keep_running;//在onStop调用后跳出循环
                }

                // Whew! Hard work done.  Slow us down, and wait until the UI thread has
                // settled down.
               //... ...
                waitForIdle();

                // Second step. Load all apps.
                if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
                loadAndBindAllApps();加载应用列表数据和绑定

                // Restore the default thread priority after we are done loading items
                //... ...
            }


            // Update the saved icons if necessary
            //... ...

            // Clear out this reference, otherwise we end up holding it until all of the
            // callback runnables are done.
            mContext = null;

            synchronized (mLock) {
                // If we are still the last one to be scheduled, remove ourselves.
                if (mLoaderTask == this) {
                    mLoaderTask = null;
                }
                mIsLoaderTaskRunning = false;
            }
        }
其中loadAndBindWorkspace会调用loadWorkspace()和bindWorkspace(),下面先分析loadWorkspace()。

LauncherModel$LoaderTask#loadWorkspace():

1. mApp.getLauncherProvider().loadDefaultFavoritesIfNecessary(0, false);

从xml文件填充数据库favorite表,如果没有填充过。默认是default_workspace.xml,源码如下:

/**
     * @param workspaceResId that can be 0 to use default or non-zero for specific resource
     */
    synchronized public void loadDefaultFavoritesIfNecessary(int origWorkspaceResId,
            boolean overridePrevious) {
        String spKey = LauncherApplication.getSharedPreferencesKey();
        SharedPreferences sp = getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE);
//如果manifest中没有写上对应的键值对,那么resId返回0
        int restrictionLayoutId = getWorkspaceLayoutIdFromAppRestrictions();
        boolean restrictionLayoutChanged = didRestrictionLayoutChange(sp, restrictionLayoutId);
        overridePrevious |= restrictionLayoutChanged;
        boolean dbCreatedNoWorkspace =
                sp.getBoolean(DB_CREATED_BUT_DEFAULT_WORKSPACE_NOT_LOADED, false);
        if (dbCreatedNoWorkspace || overridePrevious) {//如果需要初始化favorite表,进入
            SharedPreferences.Editor editor = sp.edit();

            // First try layout from app restrictions if it was found
            int workspaceResId = restrictionLayoutId;

            // If the restrictions are not set, use the resource passed to this method
            if (workspaceResId == 0) {//如果restrictionLayoutId为0,就使用调用方法传进来的resId
                workspaceResId = origWorkspaceResId;
            }

            // Use default workspace resource if none provided
            if (workspaceResId == 0) {//如果调用返回传进来的resId为0,去sharedpreference拿,默认是default_workspace
                workspaceResId = sp.getInt(DEFAULT_WORKSPACE_RESOURCE_ID, R.xml.default_workspace);
            } else {
                editor.putInt(DEFAULT_WORKSPACE_RESOURCE_ID, workspaceResId);
            }

            // Populate favorites table with initial favorites
            editor.remove(DB_CREATED_BUT_DEFAULT_WORKSPACE_NOT_LOADED);
            if (!dbCreatedNoWorkspace && overridePrevious) {
                if (LOGD) Log.d(TAG, "Clearing old launcher database");
                // Workspace has already been loaded, clear the database.
                deleteDatabase();
            }
            mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), workspaceResId);//将xml中的内容写到数据库
            editor.commit();
        }
    }

default_workspace

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值