Launcher中应用图标的显示流程

packages\apps\Launcher3\src\com\android\launcher3\Launcher.java

onCreate方法中

LauncherAppState app = LauncherAppState.getInstance(this);获取LauncherAppState的实例

mModel = app.getModel();获取LauncherModel的实例

mSharedPrefs = Utilities.getPrefs(this);

if (!mModel.addCallbacksAndLoad(this)) { 加载
            if (!internalStateHandled) {
                // If we are not binding synchronously, show a fade in animation when
                // the first page bind completes.
                mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
            }
        }

packages\apps\Launcher3\src\com\android\launcher3\LauncherAppState.java

public LauncherModel getModel() {
        return mModel;
    }



public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
        Log.v(Launcher.TAG, "LauncherAppState initiated");
        Preconditions.assertUIThread();
        mContext = context;

        mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
        mIconCache = new IconCache(mContext, mInvariantDeviceProfile, iconCacheFileName);
        mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
        mModel = new LauncherModel(this, mIconCache, AppFilter.newInstance(mContext));
        mPredictionModel = PredictionModel.newInstance(mContext);
    }

packages\apps\Launcher3\src\com\android\launcher3\LauncherModel.java

mModel.addCallbacksAndLoad(this)

public boolean addCallbacksAndLoad(Callbacks callbacks) {
        synchronized (mLock) {
            addCallbacks(callbacks);
            return startLoader();

        }
    }

    /**
     * Adds a callbacks to receive model updates
     */
    public void addCallbacks(Callbacks callbacks) {
        Preconditions.assertUIThread();
        synchronized (mCallbacksList) {
            mCallbacksList.add(callbacks);
        }
    }
public boolean startLoader() {
        // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);
        synchronized (mLock) {
            // Don't bother to start the thread if we know it's not going to do anything
            final Callbacks[] callbacksList = getCallbacks();
            if (callbacksList.length > 0) {
                // Clear any pending bind-runnables from the synchronized load process.
                for (Callbacks cb : callbacksList) {
                    mMainExecutor.execute(cb::clearPendingBinds);
                }

                // If there is already one running, tell it to stop.
                stopLoader();
                LoaderResults loaderResults = new LoaderResults(
                        mApp, mBgDataModel, mBgAllAppsList, callbacksList, mMainExecutor);
                if (mModelLoaded && !mIsLoaderTaskRunning) {
                    // Divide the set of loaded items into those that we are binding synchronously,
                    // and everything else that is to be bound normally (asynchronously).
                    loaderResults.bindWorkspace();
                    // For now, continue posting the binding of AllApps as there are other
                    // issues that arise from that.
                    loaderResults.bindAllApps();
                    loaderResults.bindDeepShortcuts();
                    loaderResults.bindWidgets();
                    return true;
                } else {
                    startLoaderForResults(loaderResults);
                }
            }
        }
        return false;
    }

Launcher是用工作区的形式来显示系统已安装的应用程序的快捷图标,每个工作区都是来描述一个抽象桌面,它由n个屏幕组成(n页),每个屏幕又分n个单元格(n个快捷图标),每个单元格用来显示一个应用程序的快捷图标。

bindWorkspace函数用来加载工作区信息,bindAllApps函数是用来加载系统已经安装的应用程序信息

LoaderResults 的方法实现为BaseLoaderResults

packages\apps\Launcher3\src\com\android\launcher3\model\BaseLoaderResults.java

public void bindAllApps() {
        // shallow copy
        AppInfo[] apps = mBgAllAppsList.copyData();
        int flags = mBgAllAppsList.getFlags();
        executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);
    }
protected void executeCallbacksTask(CallbackTask task, Executor executor) {
        executor.execute(() -> {
            if (mMyBindingId != mBgDataModel.lastBindId) {
                Log.d(TAG, "Too many consecutive reloads, skipping obsolete data-bind");
                return;
            }
            for (Callbacks cb : mCallbacksList) {
                task.execute(cb);
            }
        });
    }

CallbackTask定义在 packages\apps\Launcher3\src\com\android\launcher3\LauncherModel.java

public interface CallbackTask {

        void execute(Callbacks callbacks);
    }

mUiExecutor为packages\apps\Launcher3\src\com\android\launcher3\util\LooperExecutor.java

@Override
    public void execute(Runnable runnable) {
        if (getHandler().getLooper() == Looper.myLooper()) {
            runnable.run();
        } else {
            getHandler().post(runnable);
        }
    }

packages\apps\Launcher3\src\com\android\launcher3\Launcher.java

@Override
    public void bindAllApplications(AppInfo[] apps, int flags) {
        mAppsView.getAppsStore().setApps(apps, flags);
    }

AllAppsContainerView

packages\apps\Launcher3\src\com\android\launcher3\allapps\AllAppsContainerView.java

  public AllAppsStore getAppsStore() {
        return mAllAppsStore;
    }
mAllAppsStore.addUpdateListener(this::onAppsUpdated); 

private void onAppsUpdated() {
        boolean hasWorkApps = false;
        for (AppInfo app : mAllAppsStore.getApps()) {
            if (mWorkMatcher.matches(app, null)) {
                hasWorkApps = true;
                break;
            }
        }
        rebindAdapters(hasWorkApps);
        if (hasWorkApps) {
            resetWorkProfile();
        }
    }
private void rebindAdapters(boolean showTabs) {
        rebindAdapters(showTabs, false /* force */);
    }

    protected void rebindAdapters(boolean showTabs, boolean force) {
        if (showTabs == mUsingTabs && !force) {
            return;
        }
        replaceRVContainer(showTabs);
        mUsingTabs = showTabs;

        mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
        mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
        分页策略
        if (mUsingTabs) {
            setupWorkToggle();
            mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
            mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
            mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
            findViewById(R.id.tab_personal)
                    .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
            findViewById(R.id.tab_work)
                    .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
            onTabChanged(mViewPager.getNextPage());
        } else {
            mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
            mAH[AdapterHolder.WORK].recyclerView = null;
            if (mWorkModeSwitch != null) {
                ((ViewGroup) mWorkModeSwitch.getParent()).removeView(mWorkModeSwitch);
                mWorkModeSwitch = null;
            }
        }
        setupHeader();

        mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
        mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
    }

AllAppsStore

packages\apps\Launcher3\src\com\android\launcher3\allapps\AllAppsStore.java

/**
     * Sets the current set of apps.
     */
    public void setApps(AppInfo[] apps, int flags) {
        mApps = apps;
        mModelFlags = flags;
        notifyUpdate();
    }
private void notifyUpdate() {
        if (mDeferUpdatesFlags != 0) {
            mUpdatePending = true;
            return;
        }
        for (OnUpdateListener listener : mUpdateListeners) {
            listener.onAppsUpdated();
        }
    }

packages\apps\Launcher3\src\com\android\launcher3\allapps\AlphabeticalAppsList.java

AlphabeticalAppsList实现了OnUpdateListener 接口

/**
     * Updates internals when the set of apps are updated.
     */
    @Override
    public void onAppsUpdated() {
        // Sort the list of apps
        mApps.clear();

        for (AppInfo app : mAllAppsStore.getApps()) {
            if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) {
                mApps.add(app);
            }
        }

        Collections.sort(mApps, mAppNameComparator);

        // As a special case for some languages (currently only Simplified Chinese), we may need to
        // coalesce sections
        Locale curLocale = mLauncher.getResources().getConfiguration().locale;
        boolean localeRequiresSectionSorting = curLocale.equals(Locale.SIMPLIFIED_CHINESE);
        if (localeRequiresSectionSorting) {
            // Compute the section headers. We use a TreeMap with the section name comparator to
            // ensure that the sections are ordered when we iterate over it later
            TreeMap<String, ArrayList<AppInfo>> sectionMap = new TreeMap<>(new LabelComparator());
            for (AppInfo info : mApps) {
                // Add the section to the cache
                String sectionName = info.sectionName;

                // Add it to the mapping
                ArrayList<AppInfo> sectionApps = sectionMap.get(sectionName);
                if (sectionApps == null) {
                    sectionApps = new ArrayList<>();
                    sectionMap.put(sectionName, sectionApps);
                }
                sectionApps.add(info);
            }

            // Add each of the section apps to the list in order
            mApps.clear();
            for (Map.Entry<String, ArrayList<AppInfo>> entry : sectionMap.entrySet()) {
                mApps.addAll(entry.getValue());
            }
        }

        // Recompose the set of adapter items from the current set of apps
        updateAdapterItems();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值