SystemUI深度裁剪

SystemUI深度裁剪


前言

SystemUI AOSP包含了很多组件,
Status bars,Navigation bars,Notification,Lockscreen,Quick settings,Overview(recent task switcher),VolumeUI,PowerUI 等等,但是我们在某些Andriod设备上不会用到手机上面这么多服务,有可能只会用到Systembar(StatusBar,NavigationBar),例如车载,点餐机等等,为了让我们SystemUI更轻量,性能更优,初始化完成时间更优,那么我们最好对它进程深度裁剪.


一、裁剪思路是什么?

拿车机来说吧,一般没有powerUI,分屏,overview,截屏这些功能。很多车载项目只有状态栏,导航栏,wallpaper,通知中心,VolumeUI。那我们只保留项目中需要的服务。

二、行动吧

代码如下(示例):

<string-array name="config_systemUIServiceComponents" translatable="false">
    <item>com.android.systemui.util.NotificationChannels</item>
    <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
    <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
    <item>com.android.systemui.recents.Recents</item>
    <item>com.android.systemui.volume.VolumeUI</item>
    <item>com.android.systemui.stackdivider.Divider</item>
    <item>com.android.systemui.SystemBars</item>
    <item>com.android.systemui.usb.StorageNotification</item>
    <item>com.android.systemui.power.PowerUI</item>
    <item>com.android.systemui.media.RingtonePlayer</item>
    <item>com.android.systemui.keyboard.KeyboardUI</item>
    <item>com.android.systemui.pip.PipUI</item>
    <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
    <item>@string/config_systemUIVendorServiceComponent</item>
    <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
    <item>com.android.systemui.LatencyTester</item>
    <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
    <item>com.android.systemui.ScreenDecorations</item>
    <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
    <item>com.android.systemui.SliceBroadcastRelayHandler</item>
    <item>com.android.systemui.SizeCompatModeActivityController</item>
    <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
    <item>com.android.systemui.theme.ThemeOverlayController</item>
</string-array>

SystemUI核心组件都在这里声明的,在SystemUIService启动的,那么是不是在这里把组件注释了就能达到裁剪效果了呢。如果这么简单的话,那我就没必要写这边文章了。因为SystemUI各个组件耦合太多,如果简单的注释掉,运行会报很多错误让你一脸懵逼。这个时候有人就会说了,那我在组件代码里面再去裁剪掉,那么你真的太棒了。SystemUI组件的逻辑很多也比较复杂,这条路就算是大佬来,估计也得做很多逻辑梳理删除的工作,也要不停的调试,显然这是个笨方法。

如果对SystemUI比较了解的,其实知道所有的视图都是Window,所有的功能都是服务。既然这样那么为什么不能全都自己定义呢,一些属性逻辑参考AOSP就可以了,对的就是这个思路。

1:屏蔽掉不用的服务,只保留CommandQueue$CommandQueueStart,SystemBars

<string-array name="config_systemUIServiceComponents" translatable="false">
    <!--<item>com.android.systemui.util.NotificationChannels</item>-->
    <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
    <!--<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
    <item>com.android.systemui.recents.Recents</item>
    <item>com.android.systemui.volume.VolumeUI</item>
    <item>com.android.systemui.stackdivider.Divider</item>-->
    <item>com.android.systemui.SystemBars</item>
    <!--<item>com.android.systemui.usb.StorageNotification</item>
    <item>com.android.systemui.power.PowerUI</item>
    <item>com.android.systemui.media.RingtonePlayer</item>
    <item>com.android.systemui.keyboard.KeyboardUI</item>
    <item>com.android.systemui.pip.PipUI</item>
    <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
    <item>@string/config_systemUIVendorServiceComponent</item>
    <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
    <item>com.android.systemui.LatencyTester</item>
    <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
    <item>com.android.systemui.ScreenDecorations</item>
    <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
    <item>com.android.systemui.SliceBroadcastRelayHandler</item>
    <item>com.android.systemui.SizeCompatModeActivityController</item>
    <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>
    <item>com.android.systemui.theme.ThemeOverlayController</item>-->
</string-array>

2:AndroidManifest.xml 屏蔽掉服务注册,不然要运行时异常.


    <!-- Broadcast receiver that gets the broadcast at boot time and starts
         up everything else.
         TODO: Should have an android:permission attribute
         -->
    <service
        android:name="SystemUIService"
        android:exported="true" />

    <!--//        &lt;!&ndash; On user switch, this service is started to ensure that the associated SystemUI
                 process for the current user is started. See the resource
                 "config_systemUIServiceComponentsPerUser".
                 &ndash;&gt;
            <service android:name="SystemUISecondaryUserService"
                android:exported="false"
                android:permission="com.android.systemui.permission.SELF" />

            &lt;!&ndash; started from PhoneWindowManager
                 TODO: Should have an android:permission attribute &ndash;&gt;
            <service android:name=".screenshot.TakeScreenshotService"
                android:process=":screenshot"
                android:exported="false" />

            &lt;!&ndash; Called from PhoneWindowManager &ndash;&gt;
            <receiver android:name=".screenshot.ScreenshotServiceErrorReceiver"
                android:process=":screenshot"
                android:exported="false">
                <intent-filter>
                    <action android:name="com.android.systemui.screenshot.SHOW_ERROR" />
                </intent-filter>
            </receiver>

            <activity android:name=".screenrecord.ScreenRecordDialog"
                android:theme="@style/ScreenRecord" />
            <service android:name=".screenrecord.RecordingService" />

            <receiver android:name=".SysuiRestartReceiver"
                android:exported="false">
                <intent-filter>
                    <action android:name="com.android.systemui.action.RESTART" />

                    <data android:scheme="package" />
                </intent-filter>
            </receiver>-->

    <service
        android:name=".ImageWallpaper"
        android:exported="true"
        android:permission="android.permission.BIND_WALLPAPER" />

    <!-- <activity android:name=".tuner.TunerActivity"
               android:enabled="false"
               android:icon="@drawable/tuner"
               android:theme="@style/TunerSettings"
               android:label="@string/system_ui_tuner"
               android:process=":tuner"
               android:exported="true">
         <intent-filter>
             <action android:name="com.android.settings.action.EXTRA_SETTINGS" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
         <meta-data android:name="com.android.settings.category"
                 android:value="com.android.settings.category.ia.system" />
         <meta-data android:name="com.android.settings.summary"
                 android:resource="@string/summary_empty"/>
     </activity>

     <activity-alias android:name=".DemoMode"
               android:targetActivity=".tuner.TunerActivity"
               android:icon="@drawable/tuner"
               android:theme="@style/TunerSettings"
               android:label="@string/demo_mode"
               android:process=":tuner"
               android:exported="true">
         <intent-filter>
             <action android:name="com.android.settings.action.DEMO_MODE" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity-alias>

     <activity
         android:name=".stackdivider.ForcedResizableInfoActivity"
         android:theme="@style/ForcedResizableTheme"
         android:excludeFromRecents="true"
         android:stateNotNeeded="true"
         android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
         android:exported="false">
     </activity>

     &lt;!&ndash; Springboard for launching the share and edit activity. This needs to be in the main
          system ui process since we need to notify the status bar to dismiss the keyguard &ndash;&gt;
     <receiver android:name=".screenshot.GlobalScreenshot$ActionProxyReceiver"
         android:exported="false" />

     &lt;!&ndash; Callback for dismissing screenshot notification after a share target is picked &ndash;&gt;
     <receiver android:name=".screenshot.GlobalScreenshot$TargetChosenReceiver"
         android:exported="false" />

     &lt;!&ndash; Callback for deleting screenshot notification &ndash;&gt;
     <receiver android:name=".screenshot.GlobalScreenshot$DeleteScreenshotReceiver"
         android:exported="false" />

     &lt;!&ndash; Callback for invoking a smart action from the screenshot notification. &ndash;&gt;
     <receiver android:name=".screenshot.GlobalScreenshot$SmartActionsReceiver"
               android:exported="false"/>

     &lt;!&ndash; started from UsbDeviceSettingsManager &ndash;&gt;
     <activity android:name=".usb.UsbConfirmActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_USB"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from UsbDeviceSettingsManager &ndash;&gt;
     <activity android:name=".usb.UsbPermissionActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_USB"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from UsbDeviceSettingsManager &ndash;&gt;
     <activity android:name=".usb.UsbResolverActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_USB"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from UsbDeviceSettingsManager &ndash;&gt;
     <activity android:name=".usb.UsbAccessoryUriActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_USB"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from UsbPortManager &ndash;&gt;
     <activity android:name=".usb.UsbContaminantActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_USB"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from AdbDebuggingManager &ndash;&gt;
     <activity android:name=".usb.UsbDebuggingActivity"
         android:permission="android.permission.MANAGE_DEBUGGING"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>
     <activity-alias
         android:name=".UsbDebuggingActivityAlias"
         android:permission="android.permission.DUMP"
         android:targetActivity=".usb.UsbDebuggingActivity"
         android:exported="true">
     </activity-alias>
     <activity android:name=".usb.UsbDebuggingSecondaryUserActivity"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
     </activity>

     &lt;!&ndash; started from NetworkPolicyManagerService &ndash;&gt;
     <activity
         android:name=".net.NetworkOverLimitActivity"
         android:exported="true"
         android:permission="android.permission.MANAGE_NETWORK_POLICY"
         android:theme="@android:style/Theme.DeviceDefault.Light.Panel"
         android:finishOnCloseSystemDialogs="true"
         android:launchMode="singleTop"
         android:taskAffinity="com.android.systemui.net"
         android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
         android:excludeFromRecents="true" />

     &lt;!&ndash; started from MediaProjectionManager &ndash;&gt;
     <activity
         android:name=".media.MediaProjectionPermissionActivity"
         android:exported="true"
         android:theme="@style/Theme.SystemUI.MediaProjectionAlertDialog"
         android:finishOnCloseSystemDialogs="true"
         android:launchMode="singleTop"
         android:excludeFromRecents="true"
         android:visibleToInstantApps="true"/>

     &lt;!&ndash; started from PipUI &ndash;&gt;
     <activity
         android:name=".pip.tv.PipMenuActivity"
         android:permission="com.android.systemui.permission.SELF"
         android:exported="false"
         android:theme="@style/PipTheme"
         android:launchMode="singleTop"
         android:taskAffinity=""
         android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|locale|layoutDirection"
         android:resizeableActivity="true"
         android:supportsPictureInPicture="true"
         androidprv:alwaysFocusable="true"
         android:excludeFromRecents="true" />

     <activity
         android:name=".pip.phone.PipMenuActivity"
         android:permission="com.android.systemui.permission.SELF"
         android:theme="@style/PipPhoneOverlayControlTheme"
         android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
         android:excludeFromRecents="true"
         android:exported="false"
         android:resizeableActivity="true"
         android:supportsPictureInPicture="true"
         android:stateNotNeeded="true"
         android:taskAffinity=""
         android:launchMode="singleTop"
         androidprv:alwaysFocusable="true" />

     &lt;!&ndash; started from SliceProvider &ndash;&gt;
     <activity android:name=".SlicePermissionActivity"
         android:theme="@style/Theme.SystemUI.Dialog.Alert"
         android:finishOnCloseSystemDialogs="true"
         android:excludeFromRecents="true">
         <intent-filter>
             <action android:name="com.android.intent.action.REQUEST_SLICE_PERMISSION" />
         </intent-filter>
     </activity>

     &lt;!&ndash; platform logo easter egg activity &ndash;&gt;
     <activity
         android:name=".DessertCase"
         android:exported="true"
         android:label="@string/dessert_case"
         android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
         android:launchMode="singleInstance"
         android:screenOrientation="locked"
         android:process=":sweetsweetdesserts"
         android:excludeFromRecents="true">
         <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity>

     <activity android:name=".egg.MLandActivity"
               android:theme="@android:style/Theme.Material.NoActionBar"
               android:exported="true"
               android:icon="@drawable/icon"
               android:label="@string/mland"
               android:launchMode="singleInstance"
               android:screenOrientation="locked"
               android:process=":sweetsweetdesserts"
               android:excludeFromRecents="true">
         <intent-filter>
             <action android:name="android.intent.action.MAIN"/>
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity>

     &lt;!&ndash; a gallery of delicious treats &ndash;&gt;
     <service
         android:name=".DessertCaseDream"
         android:exported="true"
         android:label="@string/dessert_case"
         android:permission="android.permission.BIND_DREAM_SERVICE"
         android:enabled="false"
         android:process=":sweetsweetdesserts"
         >
         <intent-filter>
             <action android:name="android.service.dreams.DreamService" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </service>

     <service
         android:name=".keyguard.KeyguardService"
         android:exported="true"
         android:enabled="@bool/config_enableKeyguardService" />

     <activity android:name=".keyguard.WorkLockActivity"
               android:label="@string/accessibility_desc_work_lock"
               android:permission="android.permission.MANAGE_USERS"
               android:exported="false"
               android:excludeFromRecents="true"
               android:stateNotNeeded="true"
               android:resumeWhilePausing="true"
               android:theme="@android:style/Theme.Black.NoTitleBar">
         <intent-filter>
             <action android:name="android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity>

     <activity android:name=".Somnambulator"
         android:label="@string/start_dreams"
         android:icon="@mipmap/ic_launcher_dreams"
         android:theme="@android:style/Theme.Wallpaper.NoTitleBar"
         android:exported="true"
         android:excludeFromRecents="true"
         >
         &lt;!&ndash;
         <intent-filter>
             <action android:name="android.intent.action.CREATE_SHORTCUT" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
         &ndash;&gt;
         <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.DEFAULT" />
             <category android:name="android.intent.category.DESK_DOCK" />
         </intent-filter>
     </activity>

     <activity
         android:name=".settings.BrightnessDialog"
         android:label="@string/quick_settings_brightness_dialog_title"
         android:theme="@*android:style/Theme.DeviceDefault.QuickSettings.Dialog"
         android:finishOnCloseSystemDialogs="true"
         android:launchMode="singleInstance"
         android:excludeFromRecents="true"
         android:exported="true">
         <intent-filter>
             <action android:name="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity>

     <activity android:name=".ForegroundServicesDialog"
         android:process=":fgservices"
         android:excludeFromRecents="true"
         android:launchMode="singleTop"
         android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog">
         <intent-filter android:priority="1">
             <action android:name="android.settings.FOREGROUND_SERVICES_SETTINGS" />
             <category android:name="android.intent.category.DEFAULT" />
         </intent-filter>
     </activity>

     <activity android:name=".chooser.ChooserActivity"
             android:theme="@*android:style/Theme.NoDisplay"
             android:finishOnCloseSystemDialogs="true"
             android:excludeFromRecents="true"
             android:documentLaunchMode="never"
             android:relinquishTaskIdentity="true"
             android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
             android:process=":ui"
             android:visibleToInstantApps="true">
         <intent-filter>
             <action android:name="android.intent.action.CHOOSER" />
             <category android:name="android.intent.category.VOICE" />
         </intent-filter>
     </activity>

     &lt;!&ndash; Doze with notifications, run in main sysui process for every user  &ndash;&gt;
     <service
         android:name=".doze.DozeService"
         android:exported="true"
         android:singleUser="true"
         android:permission="android.permission.BIND_DREAM_SERVICE" />

     <receiver
         android:name=".tuner.TunerService$ClearReceiver"
         android:exported="false">
         <intent-filter>
             <action android:name="com.android.systemui.action.CLEAR_TUNER" />
         </intent-filter>
     </receiver>

     <provider
         android:name="androidx.core.content.FileProvider"
         android:authorities="com.android.systemui.fileprovider"
         android:exported="false"
         android:grantUriPermissions="true">
         <meta-data
             android:name="android.support.FILE_PROVIDER_PATHS"
             android:resource="@xml/fileprovider" />
     </provider>

     <provider android:name=".keyguard.KeyguardSliceProvider"
               android:authorities="com.android.systemui.keyguard"
               android:grantUriPermissions="true"
               android:exported="true">
     </provider>

     &lt;!&ndash; Provides list and realistic previews of clock faces for the picker app. &ndash;&gt;
     <provider
         android:name="com.android.keyguard.clock.ClockOptionsProvider"
         android:authorities="com.android.keyguard.clock"
         android:enabled="false"
         android:exported="false"
         android:grantUriPermissions="true">
     </provider>

     <receiver
         android:name=".statusbar.KeyboardShortcutsReceiver">
         <intent-filter>
             <action android:name="com.android.intent.action.DISMISS_KEYBOARD_SHORTCUTS" />
             <action android:name="com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS" />
         </intent-filter>
     </receiver>-->


    <service
        android:name="com.android.XX.notification.XXNotificationListener"
        android:exported="true"
        android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
        tools:ignore="Instantiatable">
        <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService"></action>
        </intent-filter>
    </service>
</application>

3:然后自定义StatusBar

com.android.XX.CustomStatusBar
public class XXXStatusBar extends SystemUI {
private WindowManager mWinddowManager;

@Inject
InjectionInflationController mInjectionInflater;
private XXXStatusBarWindowView mStatusBarView;
private XXXNotificationPanelView mPanelView;
private WindowManager.LayoutParams mStatusBarParams;
private ViewGroup mNavigationBarView;
private WindowManager.LayoutParams mNavigationBarParams;
private int mStatusBarHeight;

@Override
public void start() {
    putComponent(XXXStatusBar.class, this);
    mWinddowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    addStatusBarToWindows();
    addNavigationBarToWindows();
    startNotificationService();
}
}
    private void addStatusBarToWindows() {
    mStatusBarHeight = getStatusBarHeight();
    mStatusBarParams = new WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mStatusBarHeight,
            WindowManager.LayoutParams.TYPE_STATUS_BAR,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
            PixelFormat.TRANSLUCENT);
    mStatusBarParams.token = new Binder();
    mStatusBarParams.gravity = Gravity.TOP;
    mStatusBarParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
    mStatusBarParams.setTitle("StatusBar");
    mStatusBarParams.packageName = mContext.getPackageName();
    mStatusBarParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
    //mInjectionInflater.injectable(LayoutInflater.from(mContext)).inflate(R.layout.XXX_status_bar, null);
    //Log.i("gary","--mStatusBarView--:"+mInjectionInflater.injectable(LayoutInflater.from(mContext)).inflate(R.layout.XXX_status_bar, null));
    mStatusBarView = (XXXStatusBarWindowView) View.inflate(mContext, R.layout.XXX_status_bar, null);

    mPanelView = mStatusBarView.findViewById(R.id.dropdown_panel);
    mStatusBarView.setPanel(mPanelView);
    mPanelView.setBar(this);
    mStatusBarView.setBar(this);

    mWinddowManager.addView(mStatusBarView, mStatusBarParams);

}

private void addNavigationBarToWindows() {
    mNavigationBarParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
            WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
                    | WindowManager.LayoutParams.FLAG_SLIPPERY,
            PixelFormat.TRANSLUCENT);
    mNavigationBarParams.token = new Binder();
    mNavigationBarParams.setTitle("NavigationBar" + mContext.getDisplayId());
    mNavigationBarParams.accessibilityTitle = mContext.getString(R.string.nav_bar);
    mNavigationBarParams.windowAnimations = 0;
    mNavigationBarParams.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
    mNavigationBarView = (ViewGroup) View.inflate(mContext, R.layout.XXX_navigation_bar, null);
    mWinddowManager.addView(mNavigationBarView, mNavigationBarParams);
    });
}

这样自定义的状态栏,导航栏就定义出来了,具体的一些自定义功能就可以参考原生的功能实现,其实百度搜系统api支持大都可以是实现了。

2.自定义下拉面板,VolumeBar,通知中心.

1:自定义下拉面板:可以添加一个window,然后开始默认layout到负一屏的位置,用户滑动状态栏时,根据手势移动这个widow就可以了。

2:自定义VolumeBar:可以参考原生的实现方式监听volumechanged然后弹Window。

3:通知中心:自定义一个Service集成系统的NotificationListenerService 在onNotificationPosted和onNotificationRemoved处理通知。

总结

屏蔽掉原生Service,然后参考原生Service实现逻辑,实现自定义,这样自己更好控制,也能达到深度裁剪,性能优化的效果,这样会让你的SystemUI很轻量。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值