東莞制作公司網(wǎng)站的公司如何提升網(wǎng)站seo排名
目前rk3568的開(kāi)機(jī)時(shí)間有21s,統(tǒng)計(jì)的是關(guān)機(jī)后從按下 power 按鍵到顯示鎖屏的時(shí)間,當(dāng)對(duì)openharmony的系統(tǒng)進(jìn)行了裁剪子系統(tǒng),系統(tǒng)app,禁用部分服務(wù)后發(fā)現(xiàn)開(kāi)機(jī)時(shí)間僅僅提高到了20.94s 優(yōu)化微乎其微。在對(duì)init進(jìn)程的log進(jìn)行分析并解決其中的時(shí)間斷層后 開(kāi)機(jī)時(shí)長(zhǎng)優(yōu)化到了16.5s左右,可以說(shuō)是一個(gè)非常大的進(jìn)步了,下面詳細(xì)講一下優(yōu)化的過(guò)程。
一、定位 log
? openharmony支持dmesg打印kernel log和hilog 打印openharony自己的log,所以需要在開(kāi)機(jī)時(shí)抓取這兩種log來(lái)分析開(kāi)機(jī)流程。openharony的開(kāi)機(jī)流程可以參考
由于本人對(duì)于kernel了解比較少,所以對(duì)于kernel部分的優(yōu)化無(wú)法介紹。從上面的OpenHarmony init進(jìn)程的啟動(dòng)流程中我們可以知道openharmony的啟動(dòng)和Android比較類似都是init進(jìn)程去解析各種cfg文件啟動(dòng)服務(wù),那么當(dāng)kernel 內(nèi)核初始化完后,init進(jìn)程也就是pid=1的這個(gè)進(jìn)程就是開(kāi)機(jī)過(guò)程的主線程。由于openharmny的dmesg log中都攜帶了pid和函數(shù)名稱,所以我們?cè)陂_(kāi)機(jī)時(shí)抓的dmesg log中搜索pid=1可以看到開(kāi)機(jī)時(shí)主線程的打印log,先尋找是否有時(shí)間斷層的情況,比如我的設(shè)備中dmesg有一處時(shí)間斷層如下:
行 1515: [ 4.396049] [pid=1][Init][INFO][init_cmds.c:291]Mount partitions from fstab file " /vendor/etc/fstab.rk3568 "行 1517: [ 4.396782] [pid=1][BEGET][INFO][fstab.c:429]StoreFscryptPolicy:store fscrypt policy, 2:aes-256-cts:aes-256-xts行 1522: [ 4.897721] [pid=1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/resize.f2fs begin行 1524: [ 4.947110] [pid=1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/resize.f2fs failed with status 255行 1525: [ 4.947141] [pid=1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/resize.f2fs end行 1526: [ 4.947218] [pid=1][BEGET][ERROR][fstab_mount.c:394]Failed to resize.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret = 255行 1527: [ 4.947309] [pid=1][BEGET][INFO][fstab_mount.c:78]Execute /system/bin/fsck.f2fs begin行 1531: [ 7.196164] [pid=1][BEGET][ERROR][fstab_mount.c:91]Command /system/bin/fsck.f2fs failed with status 1行 1532: [ 7.196179] [pid=1][BEGET][INFO][fstab_mount.c:93]Execute /system/bin/fsck.f2fs end行 1533: [ 7.196225] [pid=1][BEGET][ERROR][fstab_mount.c:399]Failed to fsck.f2fs dir /dev/block/platform/fe310000.sdhci/by-name/userdata , ret = 1行 1538: [ 7.397003] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/userdata to /data successful行 1540: [ 7.398757] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/chip-prod to /chip_prod successful行 1542: [ 7.400545] [pid=1][BEGET][INFO][fstab_mount.c:421]Mount /dev/block/platform/fe310000.sdhci/by-name/sys-prod to /sys_prod successful行 1543: [ 7.400598] [pid=1][Init][INFO][init_cmds.c:293]Mount partitions from fstab file " /vendor/etc/fstab.rk3568 " finish ret 0
可以看到上面在4.947309 到7.196164出現(xiàn)了斷層,這段時(shí)間主線程什么都沒(méi)有輸出,并且查看log發(fā)現(xiàn)init主線程是在執(zhí)行一個(gè)命令/system/bin/fsck.f2fs,并且在執(zhí)行了2.2s后還失敗了,但是設(shè)備是可以正常開(kāi)機(jī)的。網(wǎng)上搜索發(fā)現(xiàn)fsck(file system check)用來(lái)檢查和維護(hù)不一致的文件系統(tǒng)。若系統(tǒng)掉電或磁盤發(fā)生問(wèn)題,可利用fsck命令對(duì)文件系統(tǒng)進(jìn)行檢查。由于這里是執(zhí)行失敗并且沒(méi)有什么影響,所以我這里將這個(gè)命令改成了異步執(zhí)行。這樣主線程就可以繼續(xù)往下執(zhí)行了。
在將fsck命令的執(zhí)行修改成異步執(zhí)行后發(fā)現(xiàn)這里的時(shí)間斷層消失了但是又發(fā)現(xiàn)了新的時(shí)間斷層如下:
// fsck命令時(shí)間已經(jīng)恢復(fù)
[ 4.894672] [pid=1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/resize.f2fs begin
[ 4.896229] [pid=1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/resize.f2fs end
[ 4.896445] [pid=1][BEGET][INFO][fstab_mount.c:102]Execute /system/bin/fsck.f2fs begin
[ 4.898137] [pid=1][BEGET][INFO][fstab_mount.c:118]Execute /system/bin/fsck.f2fs end
//新出現(xiàn)的時(shí)間斷層行 1943: [ 5.236372] [pid=1][BEGET][INFO][fstab.c:434]LoadFscryptPolicy start行 1944: [ 5.236398] [pid=1][BEGET][INFO][fstab.c:449]LoadFscryptPolicy success行 1945: [ 5.236533] [pid=1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc行 1992: [ 8.223549] [pid=1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 1行 1993: [ 8.232997] [pid=1][Init][INFO][fscrypt_control.c:217]Fscrypt policy init success行 1994: [ 8.233204] [pid=1][Init][INFO][key_control.c:204]version 2 loaded行 1995: [ 8.233234] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 1996: [ 8.233313] [pid=1][Init][INFO][key_control.c:110]enter行 1997: [ 8.233447] [pid=1][Init][INFO][key_control.c:78]success行 1998: [ 8.251213] [pid=1][Init][INFO][fscrypt_control.c:186]Have been init行 1999: [ 8.251311] [pid=1][Init][INFO][key_control.c:204]version 2 loaded行 2000: [ 8.251328] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 2001: [ 8.251377] [pid=1][Init][INFO][key_control.c:110]enter行 2002: [ 8.251453] [pid=1][Init][INFO][key_control.c:78]success行 2004: [ 8.261900] [pid=1][Init][INFO][fscrypt_control.c:186]Have been init行 2005: [ 8.261969] [pid=1][Init][INFO][key_control.c:204]version 2 loaded行 2006: [ 8.262016] [pid=1][Init][INFO][fscrypt_control.c:234]key path /data/service/el0/storage_daemon/sd, name /key_id行 2007: [ 8.262068] [pid=1][Init][INFO][key_control.c:110]enter行 2008: [ 8.262149] [pid=1][Init][INFO][key_control.c:78]success行 2009: [ 8.264017] [pid=1][Init][INFO][init_cmds.c:99]Sync exec: /system/bin/sdc行 2011: [ 8.338298] [pid=1][Init][INFO][init_cmds.c:112]Sync exec: /system/bin/sdc result 0 1
從上面可以知道是系統(tǒng)執(zhí)行sdc命令導(dǎo)致耗時(shí)了將近3s那么這個(gè)命令又是做什么的為什么會(huì)耗費(fèi)3s,這個(gè)我們后面再去分析。
到這里init階段的耗時(shí)基本就分析完了,同樣的我們需要接著去分析hilog,我們知道hilog是需要hilogd啟動(dòng)才能打印,所以dmesg的log中hilogd啟動(dòng)時(shí)間和hilog的打印時(shí)間應(yīng)該不會(huì)錯(cuò)的太開(kāi)。接著我們知道init服務(wù)啟動(dòng)了很多,那么哪些服務(wù)是啟動(dòng)launcher的呢?答案是foundation服務(wù)。foundation服務(wù)會(huì)啟動(dòng)AbilityManagerService,在AbilityManagerService中當(dāng)AccountManagerService發(fā)出切換user 100的請(qǐng)求時(shí)就會(huì)啟動(dòng)launcher。我在看dmesg和hilog的過(guò)程中發(fā)現(xiàn)了foundation和account的啟動(dòng)時(shí)間如下所示
[ 9.420796] [pid=1][Init][INFO][init_service_manager.c:1084]Start service foundation
[ 9.457414] [pid=1][Init][INFO][init_common_service.c:387]Service foundation(pid 536) started
[ 9.570249] [pid=1][Init][INFO][init_service_manager.c:1084]Start service accountmgr
[ 9.571380] [pid=1][Init][INFO][init_common_service.c:387]Service accountmgr(pid 553) started
可以看到foundation的啟動(dòng)時(shí)間在accountmagr之前,但是在hilog中我看到了如下log
行 24030: 07-04 11:03:24.761 553 893 I C01b00/AccountMgrService: [SendToAMSAccountStart:53]:start
行 52650: 07-04 11:03:28.073 553 893 I C01b00/AccountMgrService: [SendToAMSAccountStart:63]:end, succeed!
Account向AMS發(fā)送消息竟然耗時(shí)長(zhǎng)達(dá)3.3s,原因是由于foundation內(nèi)部包含的ability比較多,當(dāng)foundation服務(wù)啟動(dòng)時(shí),會(huì)逐個(gè)啟動(dòng)ability,openharmony的原始設(shè)定是只開(kāi)了4個(gè)線程去啟動(dòng)ability所以只有等上個(gè)ability啟動(dòng)完成后才能啟動(dòng)下個(gè)ability,這樣會(huì)延遲開(kāi)機(jī)時(shí)間,這里可以將線程池的線程擴(kuò)為2倍這樣就可以加速ability的啟動(dòng)。
在abilitymanagerserice啟動(dòng)launcher時(shí)發(fā)現(xiàn)會(huì)一直等待bootevent.bootanimation.started屬性被置為ture后才會(huì)啟動(dòng)launcher,這里也存在一定的耗時(shí),后面我們?cè)诖a分析中繼續(xù)深入了解。
二、代碼分析
2.1 fcsk的異步執(zhí)行
? 首先我們先看一下fcsk如何修改成異步執(zhí)行,首先我們先看一下這個(gè)命令是在哪里執(zhí)行的,通過(guò)前后的相關(guān)log我們可以確定他是在掛載data分區(qū)時(shí)執(zhí)行的,代碼時(shí)序圖如下:
init進(jìn)程在啟動(dòng)時(shí)在pre_init階段會(huì)去掛載系統(tǒng)的分區(qū)表,這里在掛載data分區(qū)時(shí)會(huì)調(diào)用到DoFsckF2fs去執(zhí)行文件檢查如下:
/base/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
static int DoFsckF2fs(const char* device)
{char *file = "/system/bin/fsck.f2fs";if (access(file, F_OK) != 0) {BEGET_LOGE("fsck.f2fs is not exists.");return -1;}char *cmd[] = {file, "-a", (char *)device, NULL};int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;return ExecCommand(argc, argv);
}
static int ExecCommand(int argc, char **argv)
{if (argc == 0 || argv == NULL || argv[0] == NULL) {return -1;}BEGET_LOGI("Execute %s begin", argv[0]);pid_t pid = fork();if (pid < 0) {BEGET_LOGE("Fork new process to format failed: %d", errno);return -1;}if (pid == 0) {execv(argv[0], argv);exit(-1);}int status;//這里的waitpid 參數(shù)設(shè)置為0就會(huì)掛起調(diào)用進(jìn)程(這里是init進(jìn)程)知道子進(jìn)程終止waitpid(pid, &status, 0);if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {BEGET_LOGE("Command %s failed with status %d", argv[0], WEXITSTATUS(status));}BEGET_LOGI("Execute %s end", argv[0]);return WEXITSTATUS(status);
}
想要DoFsckF2fs異步執(zhí)行,加入下面的修改即可
+//add by yuw@guideir.com for exec async commond start
+static int AsyncExecCommand(int argc, char **argv)
+{
+ if (argc == 0 || argv == NULL || argv[0] == NULL) {
+ return -1;
+ }
+ BEGET_LOGI("AsyncExecute %s begin", argv[0]);
+ pid_t pid = fork();
+ if (pid < 0) {
+ BEGET_LOGE("Fork new process to format failed: %d", errno);
+ return -1;
+ }
+ if (pid == 0) {
+ execv(argv[0], argv);
+ exit(-1);
+ }
+ int status;
+ waitpid(pid, &status, WNOHANG);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ BEGET_LOGE("Command %s failed with status %d", argv[0], WEXITSTATUS(status));
+ }
+ BEGET_LOGI("AsyncExecute %s end", argv[0]);
+ return WEXITSTATUS(status);
+}
+//add by yuw@guideir.com for exec async commond endint DoFormat(const char *devPath, const char *fsType){
@@ -192,7 +217,9 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)};int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;
- ret = ExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time start
+ ret = AsyncExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time end} else {unsigned long long realSize = size *((unsigned long long)RESIZE_BUFFER_SIZE * RESIZE_BUFFER_SIZE / FS_MANAGER_BUFFER_SIZE);
@@ -206,7 +233,9 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)};int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;
- ret = ExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time start
+ ret = AsyncExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time end}return ret;}
@@ -224,7 +253,9 @@ static int DoFsckF2fs(const char* device)};int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;
- return ExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time start
+ return AsyncExecCommand(argc, argv);
+ //modify by yuw@guideir.com for optimize boot startup time end}
其實(shí)很簡(jiǎn)單就是將ExecCommand拷貝一份修改成AsyncExecCommand后再將其中的waitpid的參數(shù)設(shè)置為WNOHANG,這樣子進(jìn)程沒(méi)有返回的時(shí)候父進(jìn)程也可以繼續(xù)執(zhí)行其他工作了,關(guān)于waitpid可以參考
2.2 sdc命令的耗時(shí)縮短
sdc命令是openharmony執(zhí)行init_global_key命令時(shí)調(diào)用過(guò)來(lái)的,流程如下:
梳理流程后發(fā)現(xiàn)是init_global_key會(huì)調(diào)用到openssl的RAND_bytes去生成隨機(jī)數(shù),經(jīng)過(guò)調(diào)查發(fā)現(xiàn)linux在開(kāi)機(jī)時(shí)由于系統(tǒng)開(kāi)機(jī)時(shí)間太短可能會(huì)導(dǎo)致系統(tǒng)的隨機(jī)熵不夠當(dāng)程序從dev/random獲取隨機(jī)數(shù)時(shí),系統(tǒng)會(huì)阻塞直到隨機(jī)熵增長(zhǎng)到一定程度才會(huì)返回。這里也是這個(gè)原因?qū)е孪到y(tǒng)阻塞。并且由于這個(gè)流程是為了生成分區(qū)解密的隨機(jī)key,無(wú)法s使用類似于上面的異步方式去執(zhí)行命令(可能會(huì)導(dǎo)致分區(qū)無(wú)法解密導(dǎo)致某些不可預(yù)置的異常),所以只能尋找其他的辦法去解決。經(jīng)過(guò)一番查找資料后發(fā)現(xiàn)這類隨機(jī)熵不夠的問(wèn)題一般都是使用工具比如haveged或者rng-tools在開(kāi)機(jī)時(shí)迅速增大隨機(jī)熵來(lái)解決的。由于我的設(shè)備是aarch64版本的,rng-tools無(wú)法編譯aarch64版本的,所以這里我選擇了haveged將他預(yù)置到系統(tǒng)中后可以正常運(yùn)行。預(yù)置完后再pre_init階段執(zhí)行“haveged -F”這條命令即可。預(yù)置完后燒錄重啟可以看到sdc命令從上面的3s左右降低到了0.5s左右,也是很大的優(yōu)化。haveged的編譯可以參考下面的鏈接:
獲取到haveged的可執(zhí)行文件后,我們就可以考慮預(yù)置到系統(tǒng)中了
首先在系統(tǒng)源代碼的base/startup/init/目錄下新建haveged文件夾并在其創(chuàng)建一個(gè)BUILD.gn,內(nèi)容如下:
import("//build/ohos.gni")
HAVEGED_DIR = "//base/startup/init/haveged"
print("prebuilt haveged")
ohos_prebuilt_executable("haveged") {source = "$HAVEGED_DIR/bin/haveged"install_enable = trueinstall_images = [ "system" ]part_name = "init"subsystem_name = "startup"
}
然后將上面我們編譯的可執(zhí)行文件放到base/startup/init/haveged的bin目錄下
最后還要在base/startup/init/bundle.json中添加我們的服務(wù):
"service_group": ["//base/startup/init/watchdog:watchdog",
++ "//base/startup/init/haveged:haveged","//base/startup/init/services/etc:watchdog.cfg","//base/startup/init/ueventd:startup_ueventd","//base/startup/init/services/etc:ueventd.cfg"
這樣haveged命令就預(yù)置到系統(tǒng)中了,剩下的就是要在哪里執(zhí)行了,我這里是把他放到了pre_init階段,修改如下:
+++ a/base/startup/init/services/etc/init.cfg"jobs" : [{"name" : "pre-init","cmds" : [
++ "exec /system/bin/haveged -F","write /proc/sys/kernel/sysrq 0","start ueventd","start watchdog_service","mkdir /data",
最后要想讓這條命令執(zhí)行成功還需要關(guān)閉selinux的權(quán)限檢查,openharmony的selinux關(guān)閉修改如下:
/base/security/selinux/selinux.gni
-- selinux_enforce = true
++ selinux_enforce = false
2.3 AbilityManagerService的啟動(dòng)
AbilityManagerService是作為foundation服務(wù)中的一個(gè)ability啟動(dòng)并且由于foundation的ability較多,AbilityManagerService的啟動(dòng)較慢。要解決啟動(dòng)慢的問(wèn)題可以通過(guò)增加ability啟動(dòng)的線程池的大小,如下:
diff --git a/safwk/services/safwk/src/local_ability_manager.cpp b/safwk/services/safwk/src/local_ability_manager.cpp
index 11f7a06..3f6fdf0 100644
--- a/safwk/services/safwk/src/local_ability_manager.cpp
+++ b/safwk/services/safwk/src/local_ability_manager.cpp
@@ -680,7 +680,7 @@ bool LocalAbilityManager::Run(int32_t saId)HILOGD(TAG, "success to add process name:%{public}s", Str16ToStr8(procName_).c_str());uint32_t concurrentThreads = std::thread::hardware_concurrency();HILOGI(TAG, "concurrentThreads is %{public}d", concurrentThreads);
- initPool_->Start(concurrentThreads);
+ initPool_->Start(2*concurrentThreads);initPool_->SetMaxTaskNum(MAX_TASK_NUMBER);FindAndStartPhaseTasks(
2.4 launcher啟動(dòng)的耗時(shí)縮短
launcher的啟動(dòng)流程如下:
簡(jiǎn)單說(shuō)一下上面的流程就是account manager啟動(dòng)后會(huì)創(chuàng)建一個(gè)account啟動(dòng)這個(gè)account時(shí)會(huì)向abilityManagerService發(fā)送一條startUser的消息,abilityManagerService在接收到消息后會(huì)啟動(dòng)launcher,最終會(huì)調(diào)用到abiltiy_manager_service的StartHighestPriorityAbility去啟動(dòng)launcher。
/foundation/ability/ability_runtime/services/abilitymgr/src/ability_manager_service.cpp
void AbilityManagerService::StartHighestPriorityAbility(int32_t userId, bool isBoot)
{....
#ifdef SUPPORT_GRAPHICSabilityWant.SetParam(NEED_STARTINGWINDOW, false);// wait BOOT_ANIMATION_STARTED to start LAUNCHER//這邊會(huì)等待bootevent.bootanimation.started屬性被置為true后才能繼續(xù)往下走WaitParameter(BOOTEVENT_BOOT_ANIMATION_STARTED.c_str(), "true", amsConfigResolver_->GetBootAnimationTimeoutTime());
#endif/* note: OOBE APP need disable itself, otherwise, it will be started when restart system everytime */(void)StartAbility(abilityWant, userId, DEFAULT_INVAL_VALUE);
}
接下來(lái)看一下bootevent.bootanimation.started是在哪里設(shè)置為true的,搜索代碼后發(fā)現(xiàn)是在下面的函數(shù)中置為ture的,
/foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
void BootAnimation::CheckExitAnimation()
{LOGI("CheckExitAnimation enter");if (!setBootEvent_) {LOGI("CheckExitAnimation set bootevent parameter");system::SetParameter("bootevent.bootanimation.started", "true");setBootEvent_ = true;}std::string windowInit = system::GetParameter("bootevent.boot.completed", "false");if (windowInit == "true") {PostTask(std::bind(&AppExecFwk::EventRunner::Stop, runner_));LOGI("CheckExitAnimation read windowInit is true");return;}
}
接著看一下CheckExitAnimation在哪里調(diào)用的
/foundation/graphic/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
void BootAnimation::Draw()
{if (picCurNo_ < (imgVecSize_ - 1)) {picCurNo_ = picCurNo_ + 1;} else {CheckExitAnimation();return;}ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw RequestFrame");auto frame = rsSurface_->RequestFrame(windowWidth_, windowHeight_);if (frame == nullptr) {LOGE("Draw frame is nullptr");return;}ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);framePtr_ = std::move(frame);auto canvas = framePtr_->GetCanvas();OnDraw(canvas, picCurNo_);ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw FlushFrame");rsSurface_->FlushFrame(framePtr_);ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
}
從上面的代碼可以看出來(lái)是當(dāng)開(kāi)機(jī)動(dòng)畫(huà)播放完成后才能被置為true。這里的意思就是只有當(dāng)開(kāi)機(jī)動(dòng)畫(huà)全部播放完成后才能啟動(dòng)launcher,rk3568的開(kāi)機(jī)動(dòng)畫(huà)有150張,幀率被設(shè)置為了30hZ這樣開(kāi)機(jī)動(dòng)畫(huà)就需要5s才能播放完畢,這樣顯然是不合理的,開(kāi)機(jī)畫(huà)應(yīng)該是用來(lái)給用戶一個(gè)提示,用來(lái)進(jìn)行系統(tǒng)的初始化的工作的。所以我這邊改成每播放一幀開(kāi)機(jī)動(dòng)畫(huà)都去檢查一下是否能夠退出動(dòng)畫(huà)。這樣也可以加速launcher的啟動(dòng),修改如下:
diff --git a/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp b/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
index 158469f..33e8bb3 100644
--- a/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
+++ b/graphic_2d/frameworks/bootanimation/src/boot_animation.cpp
@@ -52,9 +52,6 @@ void BootAnimation::Draw(){if (picCurNo_ < (imgVecSize_ - 1)) {picCurNo_ = picCurNo_ + 1;
- } else {
- CheckExitAnimation();
- return;}ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw RequestFrame");auto frame = rsSurface_->RequestFrame(windowWidth_, windowHeight_);
@@ -69,6 +66,9 @@ void BootAnimation::Draw()ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw FlushFrame");rsSurface_->FlushFrame(framePtr_);ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
+ CheckExitAnimation();}
同時(shí)也需要修改開(kāi)機(jī)動(dòng)畫(huà)讓開(kāi)機(jī)動(dòng)畫(huà)不要結(jié)束的太過(guò)突兀。至此rk3568的設(shè)備就從原來(lái)的21s優(yōu)化到了現(xiàn)在的16.5s左右,當(dāng)然系統(tǒng)內(nèi)部還有其他可以優(yōu)化的部分。這里仍然需要持續(xù)優(yōu)化。
三、錯(cuò)誤修復(fù)
在打入上述修改后發(fā)現(xiàn)系統(tǒng)的data分區(qū)發(fā)生了改變,查找原因發(fā)現(xiàn)是上面的fcsk的異步執(zhí)行導(dǎo)致的,resize.f2fs在系統(tǒng)第一次啟動(dòng)時(shí)會(huì)擴(kuò)充data分區(qū),當(dāng)data分區(qū)擴(kuò)充后后面再重啟時(shí)resize.f2fs的命令就會(huì)報(bào)錯(cuò)。所以解決方案如下:
diff --git a/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c b/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
index da4bf43c..fce50d64 100755
--- a/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
+++ b/startup/init/interfaces/innerkits/fs_manager/fstab_mount.c
@@ -43,6 +43,11 @@ extern "C" {
const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET = 4096;
const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE = 4;+//add by yuw@guideir.com for fix data partition size error start
+const char *DATA_RESIZE_KEY = "persist.sys.resize_data";
+int data_resize = 0;
+//add by yuw@guideir.com for fix data partition size error end
+
#ifdef SUPPORT_HVB
__attribute__((weak)) int UeventdSocketInit(void)
{
@@ -210,6 +215,11 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)return -1;}+ char values[2] = {0};
+ uint32_t len = sizeof(values);
+ int paramGetRet = SystemGetParameter(DATA_RESIZE_KEY,values,&len);
+ int isResize = atoi(values);
+int ret = 0;if (size == 0) {char *cmd[] = {
@@ -218,7 +228,16 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;//modify by yuw@guideir.com for optimize boot startup time start
- ret = AsyncExecCommand(argc, argv);
+ if(paramGetRet != 0 || isResize == 0){
+ ret = ExecCommand(argc, argv);
+ if(ret != 0 ){
+ data_resize = 0;
+ } else {
+ data_resize = 1;
+ }
+ } else {
+ ret = AsyncExecCommand(argc, argv);
+ }//modify by yuw@guideir.com for optimize boot startup time end} else {unsigned long long realSize = size *
@@ -234,7 +253,16 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)int argc = ARRAY_LENGTH(cmd);char **argv = (char **)cmd;//modify by yuw@guideir.com for optimize boot startup time start
- ret = AsyncExecCommand(argc, argv);
+ if(paramGetRet != 0 || isResize == 0){
+ ret = ExecCommand(argc, argv);
+ if(ret != 0 ){
+ data_resize = 0;
+ } else {
+ data_resize = 1;
+ }
+ } else {
+ ret = AsyncExecCommand(argc, argv);
+ }//modify by yuw@guideir.com for optimize boot startup time end}return ret;
diff --git a/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h b/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h
index 726ad3ed..73186707 100644
--- a/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h
+++ b/startup/init/interfaces/innerkits/include/fs_manager/fs_manager.h
@@ -42,6 +42,8 @@ extern "C" {
#define FM_MANAGER_REQUIRED_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), REQUIRED)
#define FM_MANAGER_NOFAIL_ENABLED(fsMgrFlags) FS_MANAGER_FLAGS_ENABLED((fsMgrFlags), NOFAIL)+extern int data_resize;
+extern const char *DATA_RESIZE_KEY;
typedef enum MountStatus {MOUNT_ERROR = -1,MOUNT_UMOUNTED = 0,
diff --git a/startup/init/services/init/standard/init_cmds.c b/startup/init/services/init/standard/init_cmds.c
index 5d61fbda..c56033dc 100755
--- a/startup/init/services/init/standard/init_cmds.c
+++ b/startup/init/services/init/standard/init_cmds.c
@@ -290,6 +290,9 @@ static void DoMountFstabFile(const struct CmdArgs *ctx)
{INIT_LOGI("Mount partitions from fstab file \" %s \"", ctx->argv[0]);int ret = MountAllWithFstabFile(ctx->argv[0], 0);
+ if(data_resize == 1){^M
+ SystemWriteParam(DATA_RESIZE_KEY, "1");^M
+ }^MINIT_LOGI("Mount partitions from fstab file \" %s \" finish ret %d", ctx->argv[0], ret);
}
原理時(shí)使用一個(gè)屬性來(lái)表示第一次啟動(dòng),如果是第一次啟動(dòng)那么resize.f2fs將會(huì)同步執(zhí)行,否則使用異步執(zhí)行。
為了能讓大家更好的學(xué)習(xí)鴻蒙 (Harmony OS) 開(kāi)發(fā)技術(shù),這邊特意整理了《鴻蒙 (Harmony OS)開(kāi)發(fā)學(xué)習(xí)手冊(cè)》(共計(jì)890頁(yè)),希望對(duì)大家有所幫助:https://qr21.cn/FV7h05
《鴻蒙 (Harmony OS)開(kāi)發(fā)學(xué)習(xí)手冊(cè)》
入門必看:https://qr21.cn/FV7h05
- 應(yīng)用開(kāi)發(fā)導(dǎo)讀(ArkTS)
- 應(yīng)用開(kāi)發(fā)導(dǎo)讀(Java)
HarmonyOS 概念:https://qr21.cn/FV7h05
- 系統(tǒng)定義
- 技術(shù)架構(gòu)
- 技術(shù)特性
- 系統(tǒng)安全
如何快速入門:https://qr21.cn/FV7h05
- 基本概念
- 構(gòu)建第一個(gè)ArkTS應(yīng)用
- 構(gòu)建第一個(gè)JS應(yīng)用
- ……
開(kāi)發(fā)基礎(chǔ)知識(shí):https://qr21.cn/FV7h05
- 應(yīng)用基礎(chǔ)知識(shí)
- 配置文件
- 應(yīng)用數(shù)據(jù)管理
- 應(yīng)用安全管理
- 應(yīng)用隱私保護(hù)
- 三方應(yīng)用調(diào)用管控機(jī)制
- 資源分類與訪問(wèn)
- 學(xué)習(xí)ArkTS語(yǔ)言
- ……
基于ArkTS 開(kāi)發(fā):https://qr21.cn/FV7h05
- Ability開(kāi)發(fā)
- UI開(kāi)發(fā)
- 公共事件與通知
- 窗口管理
- 媒體
- 安全
- 網(wǎng)絡(luò)與鏈接
- 電話服務(wù)
- 數(shù)據(jù)管理
- 后臺(tái)任務(wù)(Background Task)管理
- 設(shè)備管理
- 設(shè)備使用信息統(tǒng)計(jì)
- DFX
- 國(guó)際化開(kāi)發(fā)
- 折疊屏系列
- ……