前言
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。那我们只保留项目中需要的服务。
二、行动吧代码如下(示例):
- com.android.systemui.util.NotificationChannels
- com.android.systemui.statusbar.CommandQueue$CommandQueueStart
- com.android.systemui.keyguard.KeyguardViewMediator
- com.android.systemui.recents.Recents
- com.android.systemui.volume.VolumeUI
- com.android.systemui.stackdivider.Divider
- com.android.systemui.SystemBars
- com.android.systemui.usb.StorageNotification
- com.android.systemui.power.PowerUI
- com.android.systemui.media.RingtonePlayer
- com.android.systemui.keyboard.KeyboardUI
- com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- @string/config_systemUIVendorServiceComponent
- com.android.systemui.util.leak.GarbageMonitor$Service
- com.android.systemui.LatencyTester
- com.android.systemui.globalactions.GlobalActionsComponent
- com.android.systemui.ScreenDecorations
- com.android.systemui.biometrics.BiometricDialogImpl
- com.android.systemui.SliceBroadcastRelayHandler
- com.android.systemui.SizeCompatModeActivityController
- com.android.systemui.statusbar.notification.InstantAppNotifier
- com.android.systemui.theme.ThemeOverlayController
SystemUI核心组件都在这里声明的,在SystemUIService启动的,那么是不是在这里把组件注释了就能达到裁剪效果了呢。如果这么简单的话,那我就没必要写这边文章了。因为SystemUI各个组件耦合太多,如果简单的注释掉,运行会报很多错误让你一脸懵逼。这个时候有人就会说了,那我在组件代码里面再去裁剪掉,那么你真的太棒了。SystemUI组件的逻辑很多也比较复杂,这条路就算是大佬来,估计也得做很多逻辑梳理删除的工作,也要不停的调试,显然这是个笨方法。
如果对SystemUI比较了解的,其实知道所有的视图都是Window,所有的功能都是服务。既然这样那么为什么不能全都自己定义呢,一些属性逻辑参考AOSP就可以了,对的就是这个思路。
1:屏蔽掉不用的服务,只保留CommandQueue$CommandQueueStart,SystemBars
- com.android.systemui.statusbar.CommandQueue$CommandQueueStart
- com.android.systemui.SystemBars
2:AndroidManifest.xml 屏蔽掉服务注册,不然要运行时异常.
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然后dWindow。 3:通知中心:自定义一个Service集成系统的NotificationListenerService 在onNotificationPosted和onNotificationRemoved处理通知。 总结屏蔽掉原生Service,然后参考原生Service实现逻辑,实现自定义,这样自己更好控制,也能达到深度裁剪,性能优化的效果,这样会让你的SystemUI很轻量。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)