Android 10.0 Settings源码分析之主界面加载(三)

前两篇分别记录了Settings主界面
静态xml加载设置项Android 10.0 Settings源码分析之主界面加载(一)
动态从AndroidManifest.xml中加载设置项Android 10.0 Settings源码分析之主界面加载(二)
本篇主要记录设置项加载完成后,界面显示更新流程。

先来继续接着前两篇分析,来看refreshAllPreferences()方法后面逻辑:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java
refreshAllPreferences():

        final Activity activity = getActivity();
        if (activity != null) {
    
    
            Log.d(TAG, "All preferences added, reporting fully drawn");
            activity.reportFullyDrawn();
        }

        updatePreferenceVisibility(mPreferenceControllers);

当所有的preference加载完成后,通知activity进行重绘显示;调用updatePreferenceVisibility()方法:

    @VisibleForTesting
    void updatePreferenceVisibility(
            Map<Class, List<AbstractPreferenceController>> preferenceControllers) {
    
    
        final PreferenceScreen screen = getPreferenceScreen();
        if (screen == null || preferenceControllers == null || mBlockerController == null) {
    
    
            return;
        }

        final boolean visible = mBlockerController.isBlockerFinished();
        for (List<AbstractPreferenceController> controllerList :
                preferenceControllers.values()) {
    
    
            for (AbstractPreferenceController controller : controllerList) {
    
    
                final String key = controller.getPreferenceKey();
                final Preference preference = findPreference(key);
                if (preference != null) {
    
    
                    preference.setVisible(visible && controller.isAvailable());
                }
            }
        }
    }

可以看到需要满足screen、preferenceControllers、mBlockerController都不为null,才能执行后续操作。后续主要是遍历该界面所有preference设置项的controller集合mPreferenceControllers,设置是否可显示在界面上;
mBlockerController的初始化:
DashboardFragment.java#onAttach()方法:

checkUiBlocker(controllers);
    @VisibleForTesting
    void checkUiBlocker(List<AbstractPreferenceController> controllers) {
    
    
        final List<String> keys = new ArrayList<>();
        controllers
                .stream()
                .filter(controller -> controller instanceof BasePreferenceController.UiBlocker)
                .forEach(controller -> {
    
    
                    ((BasePreferenceController) controller).setUiBlockListener(this);
                    Log.d("zcl"," checkUiBlocker addkey  = " + controller.getPreferenceKey());
                    keys.add(controller.getPreferenceKey());
                });

        Log.d("zcl"," checkUiBlocker size = " + keys.size());

        if (!keys.isEmpty()) {
    
    
            mBlockerController = new UiBlockerController(keys);
            mBlockerController.start(()->updatePreferenceVisibility(mPreferenceControllers));
        }
    }

过滤该界面所有preference设置项的controller集合mPreferenceControllers内是否存在实现了BasePreferenceController.UiBlocker接口的controller元素,添加到keys集合内。目前Settings主界面未有实现,故此集合为null,即mBlockerController也为null。

即updatePreferenceVisibility()方法在主界面加载时暂不执行。
至此refreshAllPreferences()方法分析完成。

onStart()

再来看设置主界面TopLevelSettings.java的其他生命周期方法,由于其未实现onStart() 、onResume()生命周期方法,直接看父类DashboardFragment.java的onStart()方法:

    public void onStart() {
    
    
        super.onStart();
        final DashboardCategory category =
                mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
        if (category == null) {
    
    
            return;
        }
        if (mSummaryLoader != null) {
    
    
            // SummaryLoader can be null when there is no dynamic tiles.
            mSummaryLoader.setListening(true);
        }
        final Activity activity = getActivity();
        if (activity instanceof SettingsBaseActivity) {
    
    
            mListeningToCategoryChange = true;
            ((SettingsBaseActivity) activity).addCategoryListener(this);
        }
    }

获取当前界面是否存在可以动态显示的DashboardCategory对象;调用setListening方法进行“监听”,判断当前fragment所在的activity是否继承至SettingsBaseActivity,决定是否设置CategoryListener监听。

onResume()

fragment的生命周期onResume()方法:

    @Override
    public void onResume() {
    
    
        super.onResume();
        updatePreferenceStates();
    }

调用updatePreferenceStates()方法,每个controller根据自身需要去管理更新对应preference项:

    /**
     * Update state of each preference managed by PreferenceController.
     */
    protected void updatePreferenceStates() {
    
    
        final PreferenceScreen screen = getPreferenceScreen();
        Collection<List<AbstractPreferenceController>> controllerLists =
                mPreferenceControllers.values();
        for (List<AbstractPreferenceController> controllerList : controllerLists) {
    
    
            for (AbstractPreferenceController controller : controllerList) {
    
    
                if (!controller.isAvailable()) {
    
    
                    continue;
                }

                final String key = controller.getPreferenceKey();
                if (TextUtils.isEmpty(key)) {
    
    
                    Log.d(TAG, String.format("Preference key is %s in Controller %s",
                            key, controller.getClass().getSimpleName()));
                    continue;
                }

                final Preference preference = screen.findPreference(key);
                if (preference == null) {
    
    
                    Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
                            key, controller.getClass().getSimpleName()));
                    continue;
                }
                controller.updateState(preference);
            }
        }
    }

遍历mPreferenceControllers集合判断集合内每个controller元素,对应的preference是否可用可显示;对应的preference是否定义了key属性。再根据获取到的key,获取界面上对应的preference,再调用updateState()方法去更新preference状态。

updateState()

如果相关controller内部自己实现了updateState()方法,则调用其自身方法的updateState()方法;

如果未定义则调用其父类updateState()方法:
frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java

    /**
     * Updates the current status of preference (summary, switch state, etc)
     */
    public void updateState(Preference preference) {
    
    
        refreshSummary(preference);
    }

调用refreshSummary()方法,同样的如果相关controller内部自己实现了refreshSummary()方法,则调用自身实现的refreshSummary()方法;
如果未定义则调用AbstractPreferenceController.java内部的refreshSummary()方法:

    /**
     * Refresh preference summary with getSummary()
     */
    protected void refreshSummary(Preference preference) {
    
    
        if (preference == null) {
    
    
            return;
        }
        final CharSequence summary = getSummary();
        if (summary == null) {
    
    
            // Default getSummary returns null. If subclass didn't override this, there is nothing
            // we need to do.
            return;
        }
        preference.setSummary(summary);
    }

调用getSummary()方法,规则同上,获取需要显示的summary字串并设置给preference。

至此主界面设置项加载流程记录完毕。

猜你喜欢

转载自blog.csdn.net/Otaku_627/article/details/108843487