源码参考: AOSPXRef
现象效果
调试UI显示:Settings应用子界面Activity绝大部分都是SubSetting(通过dumpsys指令查看当前活动);
adb shell dumpsys activity activities | grep -i mCurrent
com.android.settings/com.android.settings.SubSettings
代码实现:
(1)Java类文件
- Settings与SubSettings中基本是空Activity,即Activity没有重写任意7大生命周期方法 (/*empty*/)
- Settings类和各子xxxSettingsActivity都继承自SettingsActivity类
- Settings类中定义各子静态xxxSettingsActivity类
- 静态内部类在AndroidManifest.xml文件中通过<meta-data>将相应的Fragment绑定起来。
package com.android.settings;
/**
* Top-level Settings activity
*/
public class Settings extends SettingsActivity {/** Settings subclasses for launching independently.*/public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
}
(2)布局文件
- 主界面:settings_main_dashboard.xml (仅android 10 以前存在,link : android-9.0.0_r61,DashboardSummary.java)
- 子界面:settings_main_prefs.xml(尚存,link : android-12.0.0_r3)
(3)代码实现
- 父类 SettingsActivity的onCreate()方法确定加载的SubSettingsActivity 布局
- setContentView(R.layout.settings_main_prefs)
- 初次启动对应的Fragment
- launchSettingFragment(initialFragmentName, intent);
public class SettingsActivity extends SettingsBaseActivityimplements IMainSwitchBar, PreferenceManager.OnPreferenceTreeClickListener,PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,ButtonBarHandler, FragmentManager.OnBackStackChangedListener { @Overrideprotected void onCreate(Bundle savedState) { super.onCreate(savedState);//...omit some codesfinal FeatureFactory factory = FeatureFactory.getFactory(this);mDashboardFeatureProvider = factory.getDashboardFeatureProvider(this);//通过判断当前是Settings还是SubSettings来确定用什么布局来显示// This is a "Sub Settings" when:// - this is a real SubSettings// - or :settings:show_fragment_as_subsetting is passed to the Intentfinal boolean isSubSettings = this instanceof SubSettings ||intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);// If this is a sub settings, then apply the SubSettings Theme for the ActionBar content// insets.// If this is in setup flow, don't apply theme. Because light theme needs to be applied// in SettingsBaseActivity#onCreate().if (isSubSettings && !WizardManagerHelper.isAnySetupWizard(getIntent())) {setTheme(R.style.Theme_SubSettings);}//设置布局界面//(0)android 9-/*mIsShowingDashboard = className.equals(Settings.class.getName());setContentView(mIsShowingDashboard ?R.layout.settings_main_dashboard : R.layout.settings_main_prefs);getSupportFragmentManager().addOnBackStackChangedListener(this);*///(1)android 10+setContentView(R.layout.settings_main_prefs);//....if (savedState != null) {// We are restarting from a previous saved state; used that to initialize, instead// of starting fresh.setTitleFromIntent(intent);ArrayList<DashboardCategory> categories =savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);if (categories != null) {mCategories.clear();mCategories.addAll(categories);setTitleFromBackStack();}} else {launchSettingFragment(initialFragmentName, intent);}}
}
- 相关页面显示类DashboardCategory.java
- 以ApnSetting为例,堆栈如下:
onCreate:312, ApnSettings (com.android.settings.network) performCreate:2685, Fragment (androidx.fragment.app) create:280, FragmentStateManager (androidx.fragment.app) moveToState:1187, FragmentManager (androidx.fragment.app) addToFirstInLastOut:1255, FragmentTransition (androidx.fragment.app) calculateFragments:1138, FragmentTransition (androidx.fragment.app) startTransitions:136, FragmentTransition (androidx.fragment.app) executeOpsTogether:2001, FragmentManager (androidx.fragment.app) removeRedundantOperationsAndExecute:1959, FragmentManager (androidx.fragment.app) execPendingActions:1861, FragmentManager (androidx.fragment.app) executePendingTransactions:489, FragmentManager (androidx.fragment.app) switchToFragment:615, SettingsActivity (com.android.settings) launchSettingFragment:403, SettingsActivity (com.android.settings) onCreate:310, SettingsActivity (com.android.settings) onCreate:222, Settings$ApnSettingsActivity (com.android.settings) performCreate:8137, Activity (android.app) performCreate:8121, Activity (android.app) callActivityOnCreate:1309, Instrumentation (android.app) performLaunchActivity:3446, ActivityThread (android.app) handleLaunchActivity:3637, ActivityThread (android.app) execute:85, LaunchActivityItem (android.app.servertransaction) executeCallbacks:135, TransactionExecutor (android.app.servertransaction) execute:95, TransactionExecutor (android.app.servertransaction) handleMessage:2105, ActivityThread$H (android.app) dispatchMessage:106, Handler (android.os) loop:223, Looper (android.os) main:7707, ActivityThread (android.app) invoke:-1, Method (java.lang.reflect) run:612, RuntimeInit$MethodAndArgsCaller (com.android.internal.os) main:997, ZygoteInit (com.android.internal.os)