android开机优化
—framework层的启动优化
文章目录
前言
androd开机启动时间优化包括三个部分,uboot, kernel,framework启动优化
有些平台用preloader和lk代替了uboot启动,本质上差不多
一、系统应用裁剪
这部分相对来说最简单,就是做系统开发的时候,不需要的系统应用可以直接裁掉,再对应的脚本中删掉对应的编译模块就行,找找device目录下面的PRODUCT_PACKAGES关键字,不需要的屏蔽掉,
另外再build\target\product下面的mk文件中, 也有一些,如telephony_system.mk,可以找到类似的mk是再哪里添加编译的,直接去掉
如果有大量的app需要裁掉, 不进行编译,可以修改build/core/main.mk,在对应的项目中新建deviceDelete.mk然后像PRODUCT_PACKAGES一样定义DELETE_PACKAGE_LIST+=xxxxx;
DELETE_LIB_LIST+=xxxxx;
PRODUCT_PACKAGES在build/core/product.mk定义_product_list_vars += PRODUCT_PACKAGES
同理增加 _product_list_vars += DELETE_PACKAGE_LIST
_product_list_vars += DELETE_LIB_LIST
然后再对应项目的device.mk中,把deviceDelete.mk加入编译,如下
$(call inherit-product, device/mediateksample/项目名/deviceDelete.mk)
在core/product.mk中搜索_producr_var_list ,然后把DELETE_PACKAGE_LIST和DELETE_LIB_LIST加上;注意这点很重要
在build/core/main.mk中的
ALL_DEFAULT_INSTALLED_MODULES := $(modules_to_install)这个前面添加, 有些编译脚本不太一样,找到这种赋值类似的地方,在前面修改即可
ifdef DELETE_PACKAGE_LIST
modules_to_install := $(filter-out $(foreach pkg, $(DELETE_PACKAGE_LIST), $(pkg) %/$(pkg).apk %/$(pkg).odex %/$(pkg).vdex), $(modules_to_install))
#sub_model := $(filter-out $(foreach pkg, $(DELETE_PACKAGE_LIST), $(pkg)), $(sub_model))
#$(foreach d,$(DELETE_PACKAGE_LIST),$(info delete-list: $(d)))
#$(foreach d,$(modules_to_install),$(info after-delete: $(d)))
endif
#要删除的不只是apk的生成, 有一些jar或者lib so的生成也可以再这里去掉
ifdef DELETE_LIB_LIST
modules_to_install := $(filter-out $(foreach pkg, $(DELETE_LIB_LIST), %/$(pkg) %/$(pkg).jar %/$(pkg).so), $(modules_to_install))
#sub_model := $(filter-out $(foreach pkg, $(DELETE_PACKAGE_LIST), $(pkg)), $(sub_model))
#$(foreach d,$(DELETE_LIB_LIST),$(info DELETE_LIB_LIST-list: $(d)))
#$(foreach d,$(modules_to_install),$(info DELETE_LIB_LIST-after-delete: $(d)))
endif
#下面这句是打印所有的进行编译的模块
$(foreach d,$(modules_to_install),$(info moudle after-delete: $(d)))
这里再添加另外一种过滤方式,用moudel的方式覆盖掉原来的app, 新建一个mudule模块,加入以下代码,然后把 module名称添加到PRODUCT_PACKAGES中,
PRODUCT_PACKAGES +=
delete_app
include $(CLEAR_VARS)
#$(warning "for add LOCAL_MODULE delete_app start")
LOCAL_MODULE := delete_app
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := FAKE
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_OVERRIDES_PACKAGES += \
CtsShimPrivPrebuilt\
WallpaperCropper \
Stk
include $(BUILD_SYSTEM)/base_rules.mk
$(LOCAL_BUILT_MODULE):
$(hide) echo "Fake: $@"
$(hide) mkdir -p $(dir $@)
$(hide) touch $@
PACKAGES.$(LOCAL_MODULE).OVERRIDES := $(strip $(LOCAL_OVERRIDES_PACKAGES))
二、系统服务裁剪
1.SyStemServer和SystemServiceRegistry修改
这部分,其实就是在systemServer启动的时候,服务的加载,有一些不需要的服务,全部屏蔽掉,当然,裁掉之后对应的一些app 也要全部裁掉, 不然, 会报错,裁错了,开机会卡在开机动画那里或者一直重复开机动画,不要怕,adb抓log ,看哪里报错,修改屏蔽掉就可以,尽量一个个修改验证,单独mm编译framework/base/services/是可以的, 要先删除out\target\product\项目名\obj\JAVA_LIBRARIES\services_intermediates这个目录,有一些平台还需要删除static和share的中间文件
\STATIC_LIBRARIES\libservices.core_intermediates
SHARED_LIBRARIES\libservices_intermediates
一般删除这三个文件夹,然后mm重新编译, push 到/system/framework/service.jar,reboot重启就能验证,下面是一些可以直接关掉的服务
VibratorService 震动器服务
ClipboardService 粘贴板服务
FingerprintService 指纹
StartCountryDetectorService 检测国家地区的
也有一些 定制系统不需要的服务,可以裁剪掉,只是会报错,不要急,看log 一步步修改错误就行
如
BatteryService 电池服务,当电量不足时发广播
WallpaperManagerService 壁纸管理服务
每个平台在裁剪这些的时候,都会有一些坑, 比如MTK的裁掉壁纸服务,在他们的duraspeed中,
会用到壁纸服务,也不知道是为啥。。这么其特,这个是mtk直接源码里面的jar包, 最后生成duraspeed的apk,中文名叫快霸,为了使用时间长的时候,自己清理内存,加速优化的,我直接裁掉了这个apk,壁纸服务才能裁掉,不然启动不了
这部分自己看一下,还要一些是自己的定制系统用不到的服务, 屏蔽掉, 不启动,报错就修改代码
然后再SystemServiceRegistry中,关掉对应的manager,当然, 有一些会报错,继续修改
2.ZygoteInit优化
这里其实没有特别大的修改,下面这个屏蔽掉,直接加载systemserver,减少时间其实不明显
/* For child process */
if (pid == 0) {
//if (hasSecondZygote(abiList)) {
// waitForSecondaryZygote(socketName);
//}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
下面的这个就比较神奇了,印象中android4.4的时候,再zygoteinit的preload方法中,是可以直接new thread进行class加载和resource加载的加速的,但是再8.0上,修改的时候才发现会问题,因为直接new thread会报错,提示你不能再zygoteinit中新建线程,很奇怪,看代码,
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();这里就禁止开线程,
ZygoteHooks.stopZygoteNoThreadCreation();这里就取消禁止,
我如果要并行加载class和resource资源,需要屏蔽这里,然后在 preload 用线程池,或者new thread来并行操作,
建议加上信号量的判断,不知道信号量的,自己百度,还可以用future类来保证运行顺序,这里不并行的话,preloader是在2S左右,并行的话,可以减少1S,测试过是可以,但是没有进行大量的测试,哪位同学修改之后的话,测试效果如何,可以留言说一下
也不知道8.0之后加上这个限制是什么原因,目前没有深入研究, 没有特别的需求可以不修改
3.开机动画修改
这个部分,其实每个平台的都不一样,以mtk的为例
首先,要清楚开机流程,开机动画启动的时候,后台实际上systemserver已经是启动的,所以开机动画不能太长,不然就是systemserver在等待动画完成,其次,动画的分辨率要合适,简单来说就是画质不要太高,避免加载时间长,同时消耗资源,另外开机声音,像mtk的就很坑,开机声音的播放需要等到mediaserver起来,然后通过mediaserver播放开机声音,等待起来要3-4s,这不是坑吗。。。 果断关闭开机声音, 当然,也可以, 直接去掉开机动画,如果需要的话,直接放一张图上去
在init.rc中start bootanim, 就是启动bootanim服务,文件在./system/etc/init/mtkbootanim.rc中,
这个是mtk自己修改的, 其他平台的名字可能不叫这个
关闭声音,关掉开机动画的话,有些有定义,具体实现看BootAnimation中的代码
比如mtk关闭声音可以修改persist.sys.mute.state=1就行
取消开机动画,可以直接在inir.rc中 ,去掉start bootanim
4.其他细节修改
out目录下的./vendor/etc/permissions/handheld_core_hardware.xml文件
找到对应项目中的整个文件,有些feature可以去掉
如 打印服务
桌面窗口组件
camera服务,有些不要的
init.rc 不启动不需要的服务。像cameraserver,一般不需要改
查看串口启动的log,一些不要的 .rc的文件,全部去掉,不运行