Android P Setting 启动流程02

  上一节讲到界面加载流程

  本节来讲以Setting根界面Dashboard为例解析数据加载流程  

  首先看到继续上一节launchSettingFragment()方法

            switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
                    mInitialTitleResId, mInitialTitle, false);

  很明显这里是加载的DashboardSummary.java这个类,我们打开这个类,看到onCreateView方法。

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
        long startTime = System.currentTimeMillis();
        final View root = inflater.inflate(R.layout.dashboard, container, false);
        mDashboard = root.findViewById(R.id.dashboard_container);
        mLayoutManager = new LinearLayoutManager(getContext());
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        if (bundle != null) {
            int scrollPosition = bundle.getInt(STATE_SCROLL_POSITION);
            mLayoutManager.scrollToPosition(scrollPosition);
        }
        mDashboard.setLayoutManager(mLayoutManager);
        mDashboard.setHasFixedSize(true);
        mDashboard.setListener(this);
        mDashboard.setItemAnimator(new DashboardItemAnimator());
        mAdapter = new DashboardAdapter(getContext(), bundle,
                mConditionManager.getConditions(), mSuggestionControllerMixin, getLifecycle());
        mDashboard.setAdapter(mAdapter);
        mSummaryLoader.setSummaryConsumer(mAdapter);
        ActionBarShadowController.attachToRecyclerView(
                getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard);
        rebuildUI();
        if (DEBUG_TIMING) {
            Log.d(TAG, "onCreateView took "
                    + (System.currentTimeMillis() - startTime) + " ms");
        }
        return root;
    }

  R.layout.dashboard 这个dashboard.xml本身是一个Recyclerview的控件布局,上面的代码大部分都是在对界面和recyclerview进行设置和基本的通用布局导入,直接看rebuildUI这个方法。rebuildUI中只有一个方法updateCategory(),阅读代码段。

    @WorkerThread
    void updateCategory() {
        final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory(
                CategoryKey.CATEGORY_HOMEPAGE);
        mSummaryLoader.updateSummaryToCache(category);
        mStagingCategory = category;
        Log.d(TAG," updateCategory mSuggestionControllerMixin = " + mSuggestionControllerMixin);
        if (mSuggestionControllerMixin == null) {
            ThreadUtils.postOnMainThread(() -> mAdapter.setCategory(mStagingCategory));
            return;
        }
        if (mSuggestionControllerMixin.isSuggestionLoaded()) {
            Log.d(TAG, "Suggestion has loaded, setting suggestion/category");
            ThreadUtils.postOnMainThread(() -> {
                if (mStagingSuggestions != null) {
                    mAdapter.setSuggestions(mStagingSuggestions);
                }
                mAdapter.setCategory(mStagingCategory);
            });
        } else {
            Log.d(TAG, "Suggestion NOT loaded, delaying setCategory by " + MAX_WAIT_MILLIS + "ms");
            mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
        }
    }

  CategoryKey.CATEGORY_HOMEPAGE 实际上就是 com.android.settings.category.ia.homepage,也就是说category是从AndroidManifest文件解析  <meta-data     android:name="com.android.settings.category" 对应属性值为com.android.settings.category.ia.homepage的Activity来获得。

下面看到getTilesForCategory这个方法,它是接口DashboardFeatureProvider中的一个方法,其实现类是DashboardFeatureProviderImpl.java阅读代码可以发现getTilesForCategory里面返回的实际上是CategoryManager.getTilesByCategory这个方法。ps:/frameworks/base/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java

    public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
        return getTilesByCategory(context, categoryKey, TileUtils.SETTING_PKG);
    }

    public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey,
            String settingPkg) {
        tryInitCategories(context, settingPkg);

        return mCategoryByKeyMap.get(categoryKey);
    }
    private synchronized void tryInitCategories(Context context, String settingPkg) {
        // Keep cached tiles by default. The cache is only invalidated when InterestingConfigChange
        // happens.
        tryInitCategories(context, false /* forceClearCache */, settingPkg);
    }

    private synchronized void tryInitCategories(Context context, boolean forceClearCache,
            String settingPkg) {
        if (mCategories == null) {
            if (forceClearCache) {
                mTileByComponentCache.clear();
            }
            mCategoryByKeyMap.clear();
            mCategories = TileUtils.getCategories(context, mTileByComponentCache,
                    false /* categoryDefinedInManifest */, mExtraAction, settingPkg);
            for (DashboardCategory category : mCategories) {
                mCategoryByKeyMap.put(category.key, category);
            }
            backwardCompatCleanupForCategory(mTileByComponentCache, mCategoryByKeyMap);
            sortCategories(context, mCategoryByKeyMap);
            filterDuplicateTiles(mCategoryByKeyMap);
        }
    }

  从红色的代码可以看到,使用的是TileUtils.getCategories()方法获取得到category。

/**
     * Build a list of DashboardCategory.
     * @param categoryDefinedInManifest If true, an dummy activity must exists in manifest to
     * represent this category (eg: .Settings$DeviceSettings)
     * @param extraAction additional intent filter action to be usetileutild to build the dashboard
     * categories
     */
    public static List<DashboardCategory> getCategories(Context context,
            Map<Pair<String, String>, Tile> cache, boolean categoryDefinedInManifest,
            String extraAction, String settingPkg) {
        final long startTime = System.currentTimeMillis();
        boolean setup = Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0)
                != 0;
        ArrayList<Tile> tiles = new ArrayList<>();
        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        for (UserHandle user : userManager.getUserProfiles()) {
            // TODO: Needs much optimization, too many PM queries going on here.
            if (user.getIdentifier() == ActivityManager.getCurrentUser()) {
                // Only add Settings for this user.
                getTilesForAction(context, user, SETTINGS_ACTION, cache, null, tiles, true,
                        settingPkg);
                getTilesForAction(context, user, OPERATOR_SETTINGS, cache,
                        OPERATOR_DEFAULT_CATEGORY, tiles, false, true, settingPkg);
                getTilesForAction(context, user, MANUFACTURER_SETTINGS, cache,
                        MANUFACTURER_DEFAULT_CATEGORY, tiles, false, true, settingPkg);
            }
            if (setup) {
                getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false,
                        settingPkg);
                if (!categoryDefinedInManifest) {
                    getTilesForAction(context, user, IA_SETTINGS_ACTION, cache, null, tiles, false,
                            settingPkg);
                    if (extraAction != null) {
                        getTilesForAction(context, user, extraAction, cache, null, tiles, false,
                                settingPkg);
                    }
                }
            }
        }

        HashMap<String, DashboardCategory> categoryMap = new HashMap<>();
        for (Tile tile : tiles) {
            DashboardCategory category = categoryMap.get(tile.category);
            if (category == null) {
                category = createCategory(context, tile.category, categoryDefinedInManifest);
                if (category == null) {
                    Log.w(LOG_TAG, "Couldn't find category " + tile.category);
                    continue;
                }
                categoryMap.put(category.key, category);
            }
            /*SPRD add for google sound settings*/
            if (tile.intent.getComponent().getClassName().equals("com.android.settings.Settings$SoundSettingsActivity")) {
                if (isSupportGoogleAudio()) {
                    category.addTile(tile);
                } else {
                    continue;
                }
            } else if (tile.intent.getComponent().getClassName().equals("com.sprd.audioprofile.AudioProfileSettings")) {
                if (!isSupportGoogleAudio()) {
                    tile.summary = context.getResources().getString(R.string.audio_profile_summary);
                    category.addTile(tile);
                } else {
                    continue;
                }
            } else if (tile.intent.getComponent().getClassName().equals("com.sprd.settings.timerpower.AlarmClock")) {
                tile.summary = context.getResources().getString(R.string.power_on_off);
                category.addTile(tile);
            } else {
                category.addTile(tile);
            }
            /*SPRD add for google sound settings end*/
            //category.addTile(tile);
        }
        ArrayList<DashboardCategory> categories = new ArrayList<>(categoryMap.values());
        for (DashboardCategory category : categories) {
            category.sortTiles();
        }
        Collections.sort(categories, CATEGORY_COMPARATOR);
        if (DEBUG_TIMING) Log.d(LOG_TAG, "getCategories took "
                + (System.currentTimeMillis() - startTime) + " ms");
        return categories;
    }

  注意到标红的变量,实质上是通过解析AndroidManifest文件中的action字段来判断是否添加进category。

  至此,Settings数据加载流程结束。

猜你喜欢

转载自www.cnblogs.com/nextbug/p/12144679.html