1.dalvik.vm.heapstartsize=8m,改为=4M后重开机
光待机其况下你就会发现使用中内存变少了,可用内存变多了,虽然你在使用桌面小工具时候
可能不会比当初还要顺,因为系统还在帮该程式划分新的内存空间,但也不至于顿
2.dalvik.vm.heapgrowthlimit=64m不用改,现在的app在前景中都吃很大内存
若改小成32m,那假设程序内存要吃到40m才会够用,该程式可能就当给你看
3..dalvik.vm.heapsize=256m(单个虚拟机可分配的最大内存256m),虽然是写单个虚拟机,但系统到底会产生多少个虚拟机...我不确定,但唯一确定是不超过实际ram的可用量
记得S3虽然是配1G RAM,但实际上看到好像是780M吧(其他好像是GPU用掉了)
780/256=3...,大概就是3个虚拟机左右(应该是这样)
想要看到更多ram的人可以将256改为128m,重开机后...你会发现可用内存又变多了...
但一样,开启新程式时候要再+128划分新的虚拟机,速度可能慢一些,但不会顿,又可节省内存的不必要浪费
1.想要装很多widget小工具到桌面的,推荐
dalvik.vm.heapstartsize=5m
dalvik.vm.heapgrowthlimit=40m
dalvik.vm.heapsize=160m
也许开启程式没那么快,但比较不卡顿,且可用内存会比较多
2.只要玩游戏、桌面很干净很无聊的、不安装其他widget小工具
dalvik.vm.heapstartsize=16m
dalvik.vm.heapgrowthlimit=64m
dalvik.vm.heapsize=384m
加载大型程式或游戏比较快,缺点是可用内存会比较小
此开机优化为相对极限式的测试,没有考虑功耗及稳定性!仅作测试及优化方向参考!当然也存在进一步优化的空间待各位发现完善!
速度的优化,很大程度是以提高CPU、DDR及EMMC的速率为基础的。所以使用的较好物料及板子,优化较为显著!
此文档主要是参考3288的《开机优化说明》编写的,针对3288 5.1公板测试。
第一部分:思路分析
开机时间包括四部分时间:
1.硬件响应power按键时间
2.Uboot 初始化系统以及加载kernel image的时间
3.Kernel 启动所需要的时间
4.Init 挂载文件系统以及Android系统启动的时间
优化思路:
1.针对影响响应时间,探讨最佳响应时间,这个主要是考虑长短按的区别。
2.Uboot 去掉不必要的模块,提高cpu,ddr的频率、emmc跑在较高频率来减少加载kernel image的时间,使用非ota固件减少kernel大小等。
3.把一些外围设备的porbe函数中的一些初始化动作放到delay work中去做,减少kernel启动时间,降低kernel中log的输出等级等。
4.优化Init 启动流程,尽可能早启动Android系统。
时间统计方法:
一、可以用serure CRT 设置:打印各部分的时间戳
各部分时间的确认:
3288 8846 sdk公板上目前启动时间是11S-12S之间。
以下是uboot及kernel几个log标志性信息:
- 10:43:59:019:DDR Version 1.00 2015928_dbg
② 10:43:59:446:U-Boot 2014.10-RK3288-10-g45ba757-dirty (Mar 30 2016 - 08:49:46)
③ 10:44:00:499:Starting kernel ...
④ 10:44:00:969:[ 0.000000] Booting Linux on physical CPU 0x500
⑤ 10:44:05:029:[ 1.136549] Freeing unused kernel memory: 352K (c0b7a000 - c0bd2000)
- uboot部分:
uboot时间为分为两部份
①~②为miniloader时间 ,此时间基本固定为400多ms ;
②~③可由u-boot编译调整优化,可控到1秒内;
- kernel:
③~④为kernel解压缩时间,450ms左右与kernel.img包大小相关,img越小,时间越短;
④~⑤可由kernel编译调整优化;
- android部分(使用logcat -b events | grep boot 打印,④~⑤间的部份时间也包含在内)
I/boot_progress_start( 182): 2233
I/boot_progress_preload_start( 182): 3308
I/boot_progress_system_run( 470): 3564
I/boot_progress_pms_start( 470): 4361
I/boot_progress_pms_system_scan_start( 470): 4481
I/boot_progress_pms_data_scan_start( 470): 6233
I/boot_progress_pms_scan_end( 470): 6243
I/boot_progress_pms_ready( 470): 6300
I/boot_progress_preload_end( 182): 6477
I/boot_progress_ams_ready( 470): 7065
I/boot_progress_enable_screen( 470): 8286
8286 减去 2233基本为android所用时间
第二部分:具体优化
开机速度与EMMC以及DDR的性能密切相关。EMMC最好能跑在HS200模式,125M(150M)以上;DDR要1G或者以上,频率越高越好。
POWER按键响应时间
这部分涉及硬件调整,暂不讨论
UBOOT时间优化
1.考虑提高uboot中cpu和ddr的频率默认是(600M,300M),
提高cpu频率为1.2G 如不稳定,请使用1G 关键字CONFIG_RKCLK_APLLB_FREQ_HIGH
提高 ddr频率为双通528M,需使用补丁中的tools/rk_tools/bin/rk32/32_LPDDR2_200MHz_LPDDR3_200MHz_DDR3_200MHz_20150318.bin文件,请慎用!此bin不适用于早期3288 ic
project u-boot/
a/arch/arm/cpu/armv7/rk32xx/clock-rk3288.c b/arch/arm/cpu/armv7/rk32xx/clock-rk3288.c
index b3ea333..066a00e 100755
--- a/arch/arm/cpu/armv7/rk32xx/clock-rk3288.c
+++ b/arch/arm/cpu/armv7/rk32xx/clock-rk3288.c
@@ -14,6 +14,8 @@ DECLARE_GLOBAL_DATA_PTR;
/* ARM/General/Codec pll freq config */
#define CONFIG_RKCLK_APLL_FREQ 600 /* MHZ */
+#define CONFIG_RKCLK_APLLB_FREQ_HIGH 1200/* 1008*/ /* MHZ */
+#define CONFIG_RKCLK_APLLL_FREQ_HIGH 816 /* MHZ */
#ifdef CONFIG_PRODUCT_BOX
#define CONFIG_RKCLK_GPLL_FREQ 300 /* MHZ */
@@ -151,6 +153,10 @@ struct pll_data {
/* apll clock table, should be from high to low */
static struct pll_clk_set apll_clks[] = {
//rate, nr, nf, no, a12_div, mp_div, m0_div, l2, atclk, pclk_dbg
+ /*_APLL_SET_CLKS(1608000,1, 67, 1, 1, 4, 2, 2, 4, 4),
+ _APLL_SET_CLKS(1512000,1, 63, 1, 1, 4, 2, 2, 4, 4),
+ _APLL_SET_CLKS(1416000,1, 59, 1, 1, 4, 2, 2, 4, 4),*/
+ _APLL_SET_CLKS(1200000,1, 50, 1, 1, 4, 2, 2, 4, 4),
_APLL_SET_CLKS(1008000,1, 84, 2, 1, 4, 2, 2, 4, 4),
_APLL_SET_CLKS(816000, 1, 68, 2, 1, 4, 2, 2, 4, 4),
_APLL_SET_CLKS(600000, 1, 50, 2, 1, 4, 2, 2, 4, 4),
@@ -747,6 +753,12 @@ void rkclk_set_pll(void)
rkclk_pll_set_rate(CPLL_ID, CONFIG_RKCLK_CPLL_FREQ, NULL);
}
+void rkclk_set_pll_high(void)
+{
+ rkclk_pll_set_rate(APLL_ID, CONFIG_RKCLK_APLLB_FREQ_HIGH, rkclk_apll_cb);
+ // rkclk_pll_set_rate(APLLB_ID, CONFIG_RKCLK_APLLB_FREQ_HIGH, rkclk_apllb_cb);
+ // rkclk_pll_set_rate(APLLL_ID, CONFIG_RKCLK_APLLL_FREQ_HIGH, rkclk_aplll_cb);
+}
/*
* rkplat clock get pll rate by id
diff --git a/board/rockchip/rk32xx/rk32xx.c b/board/rockchip/rk32xx/rk32xx.c
index fbef345..6d05abc 100755
--- a/board/rockchip/rk32xx/rk32xx.c
+++ b/board/rockchip/rk32xx/rk32xx.c
@@ -191,7 +191,9 @@ int board_late_init(void)
debug("fg_init\n");
fg_init(0); /*fuel gauge init*/
#endif
-
+ rkclk_set_pll_high();
+ rkclk_get_pll(); //如下两句修改是为了打印需要,实际量产可以去掉
+ rkclk_dump_pll();
debug("idb init\n");
//TODO:set those buffers in a better way, and use malloc?
rkidb_setup_space(gd->arch.rk_global_buf_addr);
注:
+ rkclk_get_pll();
+ rkclk_dump_pll();
这两句只为查看重设后的频率,不是必需的,去除后可加缩点时间。
另外,频率设太高,机器启动不了。
- 考虑提高nand/emmc的频率,特别是EMMC的机器,uboot中有引入emmc的DDR模式,但是默认没有开启。
开启ddr模式的方法:
diff --git a/include/configs/rk32plat.h b/include/configs/rk32plat.h
index baadd45..2339635 100755
--- a/include/configs/rk32plat.h
+++ b/include/configs/rk32plat.h
@@ -51,7 +51,7 @@
/* mmc using dma */
#define CONFIG_RK_MMC_DMA
#define CONFIG_RK_MMC_IDMAC /* internal dmac */
-#undef CONFIG_RK_MMC_DDR_MODE /* mmc using ddr mode */
+#define CONFIG_RK_MMC_DDR_MODE /* mmc using ddr mode */
/* more config for rockusb */
#ifdef CONFIG_CMD_ROCKUSB
- 把uboot作为一级loader,不用两级loader。
(这部份没在3288此次修改上使用,可自行参考3128的试试)
diff --git a/configs/rk3128_uart0_defconfig b/configs/rk3128_uart0_defconfig
index 2f39f40..bc963a1 100644
--- a/configs/rk3128_uart0_defconfig
+++ b/configs/rk3128_uart0_defconfig
@@ -1,4 +1,4 @@
-CONFIG_SYS_EXTRA_OPTIONS="RKCHIP_RK3128,SECOND_LEVEL_BOOTLOADER,UART_NUM=UART_CH0"
+CONFIG_SYS_EXTRA_OPTIONS="RKCHIP_RK3128,UART_NUM=UART_CH0"
CONFIG_ARM=y
CONFIG_ROCKCHIP_ARCH32=y
CONFIG_PLAT_RK30XX=y
- RK3128等低端芯片,kernel不要使用ZImage,建议使用Image,需配合kernel修改。
(这部份没在3288此次修改上使用)
5.uboot中默认会去dts中遍历平台能支持的所有pmic,如果单个项目pmic固定,可以不去遍历,这样也能节省时间。如:(只留下ACT8846)
diff --git a/include/configs/rk32plat.h b/include/configs/rk32plat.h
index baadd45..2339635 100755
--- a/include/configs/rk32plat.h
+++ b/include/configs/rk32plat.h
@@ -176,9 +176,9 @@
/********************************** charger and pmic driver ********************************/
#undef CONFIG_POWER_RK_SAMPLE
-#define CONFIG_POWER_RICOH619
-#define CONFIG_POWER_RK808
-#define CONFIG_POWER_RK818
+#undef CONFIG_POWER_RICOH619
+#undef CONFIG_POWER_RK808
+#undef CONFIG_POWER_RK818
#define CONFIG_POWER_ACT8846
KERNEL部分优化
- 可以在parameter中加入initcall_debug来看那些驱动的probe占用太长时间。
驱动中的probe函数中如果有msleep或mdelay操作,耗时比较长的并且不需要上电就处理的,移植到工作队列中去。比如把tp下载固件的过程移植到工作队列中:
ts->initwq = create_singlethread_workqueue("kworkqueue_initts");
if (!ts->initwq) {
dev_err(&client->dev, "Could not create initworkqueue\n");
}
INIT_WORK(&ts->initwork, gsl_ts_init_worker);
queue_work(ts->initwq, &ts->initwork);
- 同时可以考虑降低LOG的输出级别,
在parameter中添加CMDLINE:console=ttyFIQ0 androidboot.console=ttyFIQ0 loglevel=0 init
3.提高emmc的速率及使用HS200模式(物料及机器较好的可试试使用150M,nand flash无法作此优化)
diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts
index 230a75d..abf2fbc4 100755
--- a/arch/arm/boot/dts/rk3288-tb_8846.dts
+++ b/arch/arm/boot/dts/rk3288-tb_8846.dts
@@ -271,8 +272,8 @@
};
&emmc {
- clock-frequency = <100000000>;
- clock-freq-min-max = <400000 100000000>;
+ clock-frequency = <125000000>;
+ clock-freq-min-max = <400000 125000000>;
supports-highspeed;
supports-emmc;
@@ -280,7 +281,7 @@
bootpart-no-access;
//supports-DDR_MODE; //you should set the two value in your project. only close in RK3288-SDK board.
- //caps2-mmc-hs200;
+ caps2-mmc-hs200;
ignore-pm-notify;
keep-power-in-suspend;
4.去除其它不必要的加载:
diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts
index 230a75d..abf2fbc4 100755
@@ -400,11 +401,11 @@
status = "okay";
rk808: rk808@1b {
reg = <0x1b>;
- status = "okay";
+ status = "disabled";
};
rk818: rk818@1c {
reg = <0x1c>;
- status = "okay";
+ status = "disabled";
};
syr827: syr827@40 {
compatible = "silergy,syr82x";
@@ -463,21 +464,21 @@
ricoh619: ricoh619@32 {
reg = <0x32>;
- status = "okay";
+ status = "disabled";
};
bq24296: bq24296@6b {
compatible = "ti,bq24296";
reg = <0x6b>;
gpios = <&gpio0 GPIO_A7 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B0 GPIO_ACTIVE_HIGH>;
bq24296,chg_current = <1000 2000 3000>;
- status = "okay";
+ status = "disabled";
};
bq27320: bq27320@55 {
compatible = "ti,bq27320";
reg = <0x55>;
/* gpios = <&gpio0 GPIO_A7 GPIO_ACTIVE_HIGH>; */
- status = "okay";
+ status = "disabled";
};
CW2015@62 {
@@ -579,7 +580,7 @@
};
&i2c3 {
- status = "okay";
+ status = "disabled";
};
@@ -933,7 +934,7 @@
};
};
-
+/*
/include/ "rk808.dtsi"
&rk808 {
gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>;
@@ -1046,7 +1047,7 @@
};
};
};
-
+*/
&lcdc_vdd_domain {
regulator-name = "vcc30_lcd";
};
@@ -1085,6 +1086,6 @@
};
&rk3288_cif_sensor{
- status = "okay";
+ status = "disabled";
};
5.为试极致,DDR定频533不变频:(产品时不建议修改)
@@ -785,22 +786,22 @@
&clk_ddr_dvfs_table {
operating-points = <
/* KHz uV */
- 200000 1050000
+/* 200000 1050000
300000 1050000
- 400000 1100000
+ 400000 1100000*/
533000 1150000
>;
freq-table = <
/*status freq(KHz)*/
- SYS_STATUS_NORMAL 400000
- SYS_STATUS_SUSPEND 200000
+ SYS_STATUS_NORMAL 533000
+ /*SYS_STATUS_SUSPEND 200000
SYS_STATUS_VIDEO_1080P 240000
SYS_STATUS_VIDEO_4K 400000
SYS_STATUS_PERFORMANCE 528000
SYS_STATUS_DUALVIEW 400000
- SYS_STATUS_BOOST 324000
- SYS_STATUS_ISP 400000
+ SYS_STATUS_BOOST 533000
+ SYS_STATUS_ISP 400000*/
>;
bd-freq-table = <
/* bandwidth freq */
@@ -811,11 +812,11 @@
>;
auto-freq-table = <
240000
- 324000
- 396000
+/* 324000
+ 396000*/
528000
>;
- auto-freq=<1>;
+ auto-freq=<0>;
status="okay";
};
/include/ "act8846.dtsi"
6.rockchip,loader-logo-on = <0>;也可加快点
ANDROID部分优化
system/core/优化:
提频及去除selinux处理
project system/core/
diff --git a/init/Android.mk b/init/Android.mk
index b1fb135..4f25df7 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -24,7 +24,7 @@ LOCAL_SRC_FILES += bootchart.c
LOCAL_CFLAGS += -DBOOTCHART=1
endif
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+ifneq (,$(filter userdebug eng user,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_LOCAL_PROP_OVERRIDE=1 -DALLOW_DISABLE_SELINUX=1
endif
diff --git a/init/init.c b/init/init.c
index 5bfa753..fca0dc9 100644
--- a/init/init.c
+++ b/init/init.c
@@ -1124,7 +1124,7 @@ static void rk_3288_set_cpu(void)
{
int fd;
char buf[128];
- char value[16]={"1416000"};
+ char value[16]={"1608000"};//1416000
char min_freq[16]={"126000"};//126M
bool can_set_cpu = false;
diff --git a/init/util.c b/init/util.c
index 12cb11d..2fd6502 100644
--- a/init/util.c
+++ b/init/util.c
@@ -532,5 +532,9 @@ int restorecon(const char* pathname)
int restorecon_recursive(const char* pathname)
{
+ if (is_selinux_enabled() <= 0 || !sehandle)
+ {
+ return 0;
+ }
return selinux_android_restorecon(pathname, SELINUX_ANDROID_RESTORECON_RECURSE);
}
\RK3288_ANDROID5.1-SDK_V1.00_20150515\RKTools\windows\AndroidTool\rockdev\rk3288-3.10-uboot.parameter.txt
FIRMWARE_VER:5.0.0
MACHINE_MODEL:rk3288
MACHINE_ID:007
MANUFACTURER:RK3288
MAGIC: 0x5041524B
ATAG: 0x60000800
MACHINE: 3288
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
#KERNEL_IMG: 0x62008000
#FDT_NAME: rk-kernel.dtb
#RECOVER_KEY: 1,1,0,20,0
CMDLINE:console=ttyFIQ0 androidboot.selinux=disabled androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00008000@0x00006000(resource),0x00008000@0x0000e000(kernel),0x00010000@0x00016000(boot),0x00010000@0x00026000(recovery),0x0001a000@0x00036000(backup),0x00040000@0x00050000(cache),0x00002000@0x00090000(kpanic),0x00300000@0x00092000(system),0x00008000@0x00392000(metadata),0x00200000@0x0039A000(userdata),0x00020000@0x0059A000(radical_update),-@0x005BA000(user)
# in section; per section 512(0x200) bytes
#CMDLINE:console=ttyFIQ0 androidboot.baseband=N/A androidboot.selinux=permissive androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init initrd=0x62000000,0x00800000 mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00008000@0x00006000(resource),0x00008000@0x0000e000(kernel),0x00010000@0x00016000(boot),0x00010000@0x00026000(recovery),0x0001a000@0x00036000(backup),0x00040000@0x00050000(cache),0x00002000@0x00090000(kpanic),0x00100000@0x00092000(system),0x00008000@0x00192000(metadata),0x00020000@0x0039A000(radical_update),-@0x003BA000(userdata)
删减部分APK (只留下setting Search Downloads Face Search)
取消safe mode的检测,会等待1s的时间
project frameworks/base/
diff --git a/multiwindow/multiwindowcore.jar b/multiwindow/multiwindowcore.jar
index a4025cb..98b1840 100755
Binary files a/multiwindow/multiwindowcore.jar and b/multiwindow/multiwindowcore.jar differ
diff --git a/multiwindow/multiwindowpolicy.jar b/multiwindow/multiwindowpolicy.jar
index ef88dd9..5c6ce2f 100755
Binary files a/multiwindow/multiwindowpolicy.jar and b/multiwindow/multiwindowpolicy.jar differ
diff --git a/multiwindow/multiwindowservice.jar b/multiwindow/multiwindowservice.jar
index b88375b..2319428 100755
Binary files a/multiwindow/multiwindowservice.jar and b/multiwindow/multiwindowservice.jar differ
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e254727..32af376 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11556,15 +11556,8 @@ Intent.CATEGORY_LAUNCHER) */&& startFlags==0){
}
//if (goingCallback != null) goingCallback.run();
- new Thread("goingCallback thread") {
- @Override
- public void run() {
- if (goingCallback != null)
- goingCallback.run();
- }
- }.run();
-
-
+ if (goingCallback != null)
+ mHandler.post(goingCallback);
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b4c2117..a8c5570 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -993,7 +993,7 @@ public final class SystemServer {
// Before things start rolling, be sure we have decided whether
// we are in safe mode.
- final boolean safeMode = wm.detectSafeMode();
+ final boolean safeMode = false;//wm.detectSafeMode();
if (safeMode) {
mActivityManagerService.enterSafeMode();
// Disable the JIT for the system_server process
ZygoteInit处理
project frameworks/base/
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ddb0ed1..bf5ead3 100755
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -275,7 +275,7 @@ public class ZygoteInit {
}
static void preload() {
- Log.d(TAG, "begin preload");
+ /*Log.d(TAG, "begin preload");
preloadClasses();
preloadResources();
preloadOpenGL();
@@ -283,7 +283,7 @@ public class ZygoteInit {
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
- Log.d(TAG, "end preload");
+ Log.d(TAG, "end preload");*/
/*mPreloadThread.setPriority(2);
mPreloadThread.start();
媒体库处理:
project frameworks/av/
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 7ec32d2..99bf271 100755
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -31,7 +31,7 @@
namespace android {
Mutex MediaProfiles::sLock;
-bool MediaProfiles::sIsInitialized = false;
+bool MediaProfiles::sIsInitialized = true;
MediaProfiles *MediaProfiles::sInstance = NULL;
const MediaProfiles::NameToTagMap MediaProfiles::sVideoEncoderNameMap[] = {
使用小UI:
project device/rockchip/common/
diff --git a/device.mk b/device.mk
index d522866..2b48360 100755
--- a/device.mk
+++ b/device.mk
@@ -20,9 +20,10 @@ $(shell python $(LOCAL_PATH)/auto_generator.py $(TARGET_PRODUCT) preinstall_del)
$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk)
-PRODUCT_AAPT_CONFIG ?= normal large xlarge hdpi xhdpi xxhdpi
-PRODUCT_AAPT_PREF_CONFIG ?= xhdpi
-
+#PRODUCT_AAPT_CONFIG ?= normal large xlarge hdpi xhdpi xxhdpi
+#PRODUCT_AAPT_PREF_CONFIG ?= xhdpi
+PRODUCT_AAPT_CONFIG ?= normal hdpi
+PRODUCT_AAPT_PREF_CONFIG ?= hdpi
裁剪加载类
./frameworks/base/preloaded-classes 少加载会影响 App 启动速度 , 此地优化空间不大
./frameworks/base/core/res/ 会被打包成 framework-res.apk,确保没有冗余的资源图片,可以挨个检查图片、XML是否在系统中有用到;
二 Build 预提取 odex
通常手机升级后会显示 正在优化第*个应用,总共 * 个应用 这个就是在对 APK 做 dexopt 的优化。
odex 是 APK 中提取出来的可运行文件.
APK 中的 class.dex 会在 dex 优化过程众被转化为 odex 文件存放.
正常的开机过程中 , 系统需要在开机过程中从 APK 提取 dex 再运行.
所以我们可以在 Build 过程中预先提取 dex 将其优化为 odex , 进而达到加快启动速度的目的.
2.1 对于内置 SourceCode 的 APK
在Android.mk中都会通过include $(BUILD_PACKAGE)来编译,会调用到package.mk来提取 odex.
2.2 对于通过 prebuilt 方式内置的 APK
通过 prebuilt 方式预置的 APK , 默认不会被提取 odex.
2.3 设置方法
2.3.1 对于 App 的Android.mk
LOCAL_DEX_PREOPT := false
1
如果设置为 false 可以使整个系统使用提前优化的时候,某个app不使用提前优化。
如果设置为 true 则编译生成的文件有 oat 文件, 即在 build 过程中被提前优化.
2.3.2 对于 system.img 如果设置了:
WITH_DEXPREOPT := true
1
打开这个宏之后,无论是有源码还是无源码的预置apk预编译时都会提取odex文件。
如有发现user版本未提取odex,请检查device.mk文件配置:
ifeq ($(TARGET_BUILD_VARIANT),user)
WITH_DEXPREOPT := true
DONT_DEXPREOPT_PREBUILTS := true //此句注释掉
endif
1
2
3
4
对于64bit的芯片,若apk只有32bit的lib或者只能作为32bit运行,请在预置apk时在android.mk中添加下边的TAG标记此apk为32bit:
LOCAL_MULTILIB :=32
1
但是这个会导致 system.img 中的所有东西都被 pre-optimized , 即 system.img 会变得很大. 此时可能需要调大 system.img 的大小限制.
在编译的时候,/system/framework/ 目录下面的jar包,和 /system/app,/system/priv-app/,/system/vendor/app 下面的apk文件,都会在编译时,做odex优化。
2.3.3 对于 jar 包 , 如果不想jar包做odex优化,可以在/buid/core/java_library.mk文件中设置:
LOCAL_DEX_PREOPT := false
1
这样在编译时,jar包就不会做odex优化。
三 开机动画
bootanimation 时间
1. 最好不要超过 system_server 启动时间 (11s) ( 63385.657304 : Android:SysServerInit_START 到 Android:SysServerInit_END)
2. 不要播放 mp3
3. bootanimation.zip 图片越少越好
四 无用的服务
/frameworks/base/services/java/com/android/server/SystemServer.java
比如:DropBoxManagerService和调试相关,可以异步加载或者直接阉割掉;
比如:PinnerService没有配置相关则可以去除;
其他Service可以挨个排查.
非必要的服务可以放在 system_server 进程外启动.
五 App 的优化
5.1 App 本身优化
尽量少把APP设置为persist;
优化每一个有源码的persist APP;使他们启动尽可能快;
com.android.systemui(PersistAP)
com.mediatek.ims(PersistAP)
com.android.phone(PersistAP)
com.android.settings
1
2
3
4
精简apk包;
(1)删除没有用到的,图片、资源文件、没有用到的jar包文件、不需要使用的so文件;
(2)预置自己的APP,假如设备只会加载drawable-xxhdpi中的资源,那么可以在drawable包重复的资源可以直接删除;
(3)预置自己的APP,假如设置只支持英文,values-da、values-fa这样的多语言支持资源都可以删除;
(4)apk中只保留和系统适配的so文件,比如:armv7和arm64的so文件;
Application的onCreate方法中不要有耗时的代码段;
通过修改–compiler-filter 为 speed、quick、speed-profile来提高 APK 的启动速度;
speed 模式优化的类较多,这时优化后的vdex、odex的文件较大,应用启动过程包括映射apk文件的过程,文件偏大导致有一定的时间损耗;
但 speed 模式优化后,Java类执行更快;所以这个需要针对具体的应用多次验证,没有普适性;
5.2 系统 App 裁剪
PackageManagerService
scanDirTracedLI
(1)减少预置APP的数量(对开机速度会有较为明显的提升);
(2)删除没有必要的apk包;
(3)单线程scan分区里面的apk并不一定能充分使用IO资源,尝试改为多线程异步scan;
(4)精简系统,把系统中用不到的apk包、有重复功能的apk移除,这样既可以使系统有更大的剩余存储空间又可以减少scan的时间,加快开机;