一、优化启动时间
启动时间是影响用户体验的重要指标之一,优化启动时间可以让用户更快地进入操作系统。对于Android系统而言,他的启动顺序是:bootloader -> kernel -> init -> zygote -> launcher。
提升Android系统启动速度,我们可以从以下几个方面入手:
1、优化bootloader的启动时间
if (mode != fastboot) { avb_result_t load_result = avb_slot_verify(slot, AVB_SLOT_VERIFY_FLAGS_NONE, &loaded_partitions); if (load_result != AVB_SLOT_VERIFY_RESULT_OK) { bootloader_error("Public key for verifying %s did not validate images!\n", slot_suffix); continue; } }
bootloader阶段的启动时间占总启动时间的比例较小,但是它对整个启动过程进行了重要的准备工作。优化bootloader可以从如何加载kernel以及如何初始化设备等方面进行优化。
2、优化kernel的启动时间
int init(void *handle) { ... while (1) { init_time.start_time = gettime(); ci = console_cmdline_init(handle); init_time.cmdline_time = time_diff_us(init_time.start_time, gettime()); init_time.start_time = gettime(); err = boot_linux_kernel(ci); init_time.kernel_time = time_diff_us(init_time.start_time, gettime()); printf("kernel boot time = %lluus\n\n", init_time.kernel_time); if (err >= 0) printf("\nerror: kernel %d returned error %d\n\n", curr_slot.slot_number, err); free(ci); } }
kernel初始化进程是整个启动过程中占用时间最长的环节,若要优化系统启动时间,优化kernel的启动时间是关键。优化kernel的启动时间可以通过减少内核初始化时的处理和检测,提高kernel的启动效率,从而减少整个系统的启动时间。
3、优化init进程的启动时间
int main(int argc, char *argv[]) { ... if (init_parse_cmdline()) { panic("Failed to parse kernel command line"); } property_init(); export_oem_lock_status(); selinux_initialize(); signal_init(); time_init(); subcontext_init(); option_init(); set_usb_controller(); device_init(); if (mount_devices()) { panic("Failed to mount specified partitions"); } healthd_mode_init(); ... }
init进程启动时间时间也很长,而init进程主要完成的任务就是进行系统初始化以及启动第一个进程zygote,提高init进程启动速度也可以通过减少处理和检测的方式提高启动效率。
二、降低系统启动时间
降低系统启动时间也是提高用户体验的重要手段。我们可以从下面的几个方面入手:
1、减少启动服务的数量
$count = 0
while [ $count -le 5 ]; do
stop conman
sleep 2
setprop persist.service.bdroid.bdaddr 22:33:44:55:66:78
start conman
sleep 2
ps -eo cmd | grep "bluetoothd --hci" | grep -v grep > /dev/null
if [ $? -eq 0 ]; then
count=$[$count+1]
else
count=0
fi
done
启动服务的数量对于系统的启动时间有着显著的影响,启动服务过多会导致系统启动时间变长,因此我们可以通过减少启动服务的数量来降低系统启动时间。
2、优化启动服务的顺序
class NfcService extends INfcService.Stub {
public NfcService(Context context) {
mContext = context;
mNfcAdapterFactory = new NfcAdapterVendorAdapterFactory(mContext);
mTagLifecycleAdapter = new TagLifecycleAdapter(mContext);
mBeamShareActivityInfoAdapter = null;
}
}
启动服务的顺序也会影响到系统的启动速度,因此我们可以通过优化启动服务的顺序来提高系统的启动速度。
3、减少文件读写量
if (!fd || (type == INPUT_BOOL && fscanf(fd, "%d", &value) != 1) ||
(type == INPUT_EVENT && fscanf(fd, "%d %d %d", &type, &code, &value) != 3) ||
fscanf(fd, "%*[^\n]\n") != 0) {
ALOGE("%s: could not read from event fd, %s", __func__, strerror(errno));
fclose(fd);
return;
}
在启动过程中,文件读写量也会影响整体启动速度,因此,我们可以通过减少文件读写量的方式来降低系统的启动时间。
三、启用缓存来加速启动
1、通过缓存kernel来加速启动
bootimg = malloc(sizeof(*bootimg));
if (!bootimg) die("out of memory");
bootimg = mkbootimg(bootimg,
cmdlinelen ? cmd + strlen(BOOTIMG_DEFAULT_KERNEL_ARGS) + 1 : cmd,
cmdlinelen ? cmd : "",
base, pagesize, tag,
dtb, hdr->second_size,
&image_start, &image_size);
通过缓存kernel可以大幅提高下次启动的速度,当系统下一次启动时,bootloader会读取缓存中的kernel,从而使启动速度变得更快。
2、通过缓存页面来加速启动
total_size = cache_file_max_size(cache_dir, CACHE_DATA_FILENAME);
if (total_size == -1) {
return 0;
}
dev = device_create(ctx);
if (!dev) {
fprintf(stderr, "create device failed: %s\n", strerror(errno));
return 0;
}
cache_device = *(const struct fastboot_device*)dev->vtable;
cache_device.cookie = &cache_device;
cache_device.transport = &cache_transport_vtab;
Android系统中还有一种叫做system-cache的优化方案,可以通过缓存页面来加速启动,启用缓存之后,下一次启动将会从缓存中读取页面,而不是直接从磁盘读取。系统启动时间会因此缩短。
3、通过缓存APK来加速启动
layoutIfNeeded();
GeneratedStub.stub().value = context.getResources().getBoolean(R.bool.is_generator_installed);
GeneratedStub.stub().value = false;
mAppsOrderedByLaunch = loadAllAppsByBatch( pm );
if (mAppsOrderedByLaunch == null) {
mAllAppsLoaded = false;
if (mIconCache != null) {
mIconCache.flush();
}
}
缓存APK是一种用于加速系统启动的有效手段。系统会在启动时缓存需要的APK文件,这样下次启动时,APK文件就可以直接从缓存中加载,而不是重新从磁盘读取,从而加速系统的启动。