本文链接 http://wossoneri.github.io/2018/08/30/[Android][Framework]crop-SystemServer-and-SystemFeature/
SystemServer服务裁剪
有些系统,因为应用场景的不同,需要的服务也不一样。比如Android Things,为了应对IOT的应用场景,它就裁剪掉了很多服务。下面介绍一下裁剪服务的方法。
关于服务,要提一下SystemServer,具体介绍见另一篇文章:http://wossoneri.github.io。SystemServer启动了系统的核心服务,除此之外,SystemServer还启动了很多其他服务,具体是在startOtherServices()方法中。我们要裁剪不需要的服务就可以从这里入手。
比如要关闭打印机服务:
可以直接把相关启动服务的代码注释掉:
//mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
当然这样修改后,以后如果要再打开,还需要再次修改SystemServer,然后编译jar包,push到设备使其生效。
所以建议使用下面的改法:
首先定义boolean变量,从全局属性读取配置,
boolean disablePrinter = SystemProperties.getBoolean("config.disable_printer", false);
然后在启动服务的代码段添加对这个属性的判断:
if (!disablePrinter && mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
}
之后在MakeFile增加自定义的系统权限:
PRODUCT_PROPERTY_OVERRIDES += \
config.disable_printer=true
以后如果要打开这个服务,就把true变成false就可以了。
如果要调试,从修改设备的 /system/build.prop
然后重启即可。非常方便有木有!
如果要修改,删掉out目录下的build.prop,重新编译system(或者直接修改build.prop然后make snod),烧录启动系统之后,运行如下命令进行验证:
service check printer
这样就不会再启动不需要的服务了。
裁剪服务引发的问题
服务不是你不让它Start就完事儿了,系统那么大,总有一些地方会获取服务对象做一些调用处理。比如我们刚裁减掉了打印机服务,然后打开Settings就遇到了crash:
E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: Process: com.android.settings, PID: 3496
E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/com.android.settings.Settings}: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List android.print.IPrintManager.getPrintServices(int, int)' on a null object reference
E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
E AndroidRuntime: at android.app.ActivityThread.-wrap12(ActivityThread.java)
E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6119)
E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:790)
E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'java.util.List android.print.IPrintManager.getPrintServices(int, int)' on a null object reference
E AndroidRuntime: at android.print.PrintManager.getPrintServices(PrintManager.java:635)
E AndroidRuntime: at android.print.PrintServicesLoader.onStartLoading(PrintServicesLoader.java:88)
E AndroidRuntime: at android.content.Loader.startLoading(Loader.java:290)
E AndroidRuntime: at android.app.LoaderManagerImpl$LoaderInfo.start(LoaderManager.java:283)
E AndroidRuntime: at android.app.LoaderManagerImpl.installLoader(LoaderManager.java:579)
E AndroidRuntime: at androi