Android Settings 跳转流程

作者: 孤街酒客0911 | 来源:发表于2022-08-03 14:40 被阅读0次
    点击事件回调堆栈.png

    我们知道在Settings中,各模块的Fragment基本都继承了DashboardFragment,当有点击事件时,就会回调DashboardFragment中的onPreferenceTreeClick()方法:

     @Override
        public boolean onPreferenceTreeClick(Preference preference) {
    
            final Collection<List<AbstractPreferenceController>> controllers =
                    mPreferenceControllers.values();
            for (List<AbstractPreferenceController> controllerList : controllers) {
                for (AbstractPreferenceController controller : controllerList) {
                    if (controller.handlePreferenceTreeClick(preference)) {
                        // log here since calling super.onPreferenceTreeClick will be skipped
                        writePreferenceClickMetric(preference);
                        return true;
                    }
                }
            }
            return super.onPreferenceTreeClick(preference);
        }
    

    在onPreferenceTreeClick()方法中可以根据preference的key做事件拦截,如果不会拦截,将会调用到父类InstrumentedPreferenceFragment的onPreferenceTreeClick()方法:

        @Override
        public boolean onPreferenceTreeClick(Preference preference) {
            writePreferenceClickMetric(preference);
            return super.onPreferenceTreeClick(preference);
        }
    

    在该方法中,又将会调用到androidx中的PreferenceFragmentCompat方法中,由于androidx中源码不开放,就不做分析,但下一步回将调到SettingsActivity中的onPreferenceStartFragment()方法:

        @Override
        public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
            new SubSettingLauncher(this)
                    .setDestination(pref.getFragment())
                    .setArguments(pref.getExtras())
                    .setSourceMetricsCategory(caller instanceof Instrumentable
                            ? ((Instrumentable) caller).getMetricsCategory()
                            : Instrumentable.METRICS_CATEGORY_UNKNOWN)
                    .setTitleRes(-1)
                    .launch();
            return true;
        }
    

    在该方法中由SubSettingLauncher类里面的launch()方法,启动了对应的空Activity,但在Setting中各模块的Activity都时继承SettingsActivity的。但对应的空Activity启动时,就会回执行SettingsActivity中onCreate()方法:

    @Override  
        protected void onCreate(Bundle savedState) {  
            super.onCreate(savedState);  
            long startTime = System.currentTimeMillis();  
            //工厂类实现方法com.android.settings.overlay.FeatureFactoryImpl.java  
            final FeatureFactory factory = FeatureFactory.getFactory(this);  
            //获取菜单信息的工厂类,实现类为DashboardFeatureProviderImpl.java  
            mDashboardFeatureProvider = factory.getDashboardFeatureProvider(this);  
            mMetricsFeatureProvider = factory.getMetricsFeatureProvider();  
     // 第一步    从intent信息中获取<meta-data/>标签名为"com.android.settings.FRAGMENT_CLASS"的值(下文用于加载Fragment的类名)  
            getMetaData();  
    
     // 第二步
          final Intent intent = getIntent();
          if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
              getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
          }
          
            //获取上面getMetaData()得到的类名  
            final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);  
            //是否为快捷进入方式(如从其它的应用进入Settings的某个设置项)  
            mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||  
                    intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);  
            ... ...  
         
            if (savedState != null) {  
              ... ...  
            } else {  
     //  第三步   加载布局  
                launchSettingFragment(initialFragmentName, isSubSettings, intent);  
            }  
      
            ... ...  
        } 
    

    最终在 launchSettingFragment(initialFragmentName, isSubSettings, intent) 方法中加载相对应的Fragment布局,(若注释这句话:你会发现 Activity 启动了,却没有布局)。

    相关文章

      网友评论

        本文标题:Android Settings 跳转流程

        本文链接:https://www.haomeiwen.com/subject/cbnswrtx.html