chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

OpenHarmony源碼剖析之ACE(JavaScript運行環(huán)境初始化)

OpenAtom OpenHarmony ? 來源:51CTO ? 作者:張亮亮 ? 2021-11-18 10:40 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

張亮亮

深圳開鴻數(shù)字產(chǎn)業(yè)發(fā)展有限公司

簡介

JS UI 框架引擎ACE全稱 Ability Cross-platform Environment,是 OpenHarmony 標準系統(tǒng)上的UI框架。ACE:結(jié)合了 OpenHarmony 系統(tǒng)的基礎(chǔ)組件 Ability,開源 jsframework 框架,開源 js 引擎 quickjs,開源跨平臺 UI 框架 flutter,開源渲染引擎 skia 以及各種平臺能力 API 等共同構(gòu)筑了 OpenHarmony 標準系統(tǒng) javacript 應用開發(fā)的基礎(chǔ)。

1.1 OpenHarmony 架構(gòu)圖

9b9230c6-47d2-11ec-b939-dac502259ad0.png

1.2 ACE UI框架引擎圖

9cadf030-47d2-11ec-b939-dac502259ad0.png

1.3 ACE 主要構(gòu)成

1. JavaScript前端框架

目前 OpenHarmony 標準系統(tǒng)采用主流的類 Web 范式,對開源的 Weex 框架中的 jsframework 做定制化,采用 ts 開發(fā),主要包括編程模型 MVVM、組件、API、頁面路由以及事件處理。

2. JavaScript引擎

目前 OpenHarmony 標準系統(tǒng)使用的是開源 quickjs 引擎,提供 JS 語言運行時和執(zhí)行上下文,提供 js 的解析和 jsframework 的加載。

3. 中間轉(zhuǎn)換層

中間轉(zhuǎn)換層也就是 JS 橋接層,實現(xiàn)前端開發(fā)框架到 UI 后端引擎和 JS 引擎的對接。

4. 聲明式UI后端引擎

C++構(gòu)建的UI后端引擎,包括 UI 組件、布局視圖、動畫事件、自繪制選軟管線。

5. 渲染引擎

目前 OpenHarmony 標準系統(tǒng)復用了開源跨平臺 UI 框架 flutter 引擎提供基礎(chǔ)的圖形渲染能力。

6. 平臺適配層

目前 OpenHarmony 標準系統(tǒng)的適配層完成了 OpenHarmony 平臺和 IDE 的 previewer 的適配,將平臺依賴聚焦到平臺相關(guān)的畫布、通用線程以及事件處理機制等少數(shù)接口上,為跨平臺提供相應的基礎(chǔ)設施,實現(xiàn)跨平臺一致化的 UI 渲染。

7. 能力擴展層

為擴展 ACE 能力提供的插件機制,平臺其他子系統(tǒng)可以利用插件機制開發(fā)相關(guān)能力的 js 接口,為應用層提供相應的能力支持。通過 napi 提供引擎無關(guān)的插件實現(xiàn)機制,保證接口的 ABI 兼容性。

基礎(chǔ)知識

2.1 代碼結(jié)構(gòu)
/foundation/ace/ace_engine├── adapter                       # 平臺適配目錄│   ├── common|   ├── ohos                      # ohos平臺適配目錄│   └── preview                   # IDE preview平臺適配目錄├── frameworks                    # 框架代碼│   ├── base                      # 基礎(chǔ)庫│   ├── bridge                    # 前后端對接層│   └── core                      # 聲明式UI后端引擎目錄/third_party/jsframework          # JavaScript前端框架/third_party/quickjs              # JavaScript引擎/third_party/flutter#flutterengine提供跨平臺自渲染引擎

2.2 ACE框架類圖

9ce025a0-47d2-11ec-b939-dac502259ad0.png

(點擊圖片查看高清大圖) 2.3 線程模型

ACE JS 應用啟動時會創(chuàng)建一系列線程,形成獨立的線程模型,以實現(xiàn)高性能的渲染流程。

Platform線程:當前平臺的主線程,也就是應用的主線程,主要負責平臺層的交互、應用生命周期以及窗口環(huán)境的創(chuàng)建。

JS線程:JS 前端框架的執(zhí)行線程,應用的 JS 邏輯以及應用 UI 界面的解析構(gòu)建都在該線程執(zhí)行。

UI線程:引擎的核心線程,組件樹的構(gòu)建以及整個渲染管線的核心邏輯都在該線程:包括渲染樹的構(gòu)建、布局、繪制以及動畫調(diào)度。

GPU線程:現(xiàn)代的渲染引擎,為了充分發(fā)揮硬件性能,都支持 GPU 硬件加速,在該線程上,會通過系統(tǒng)的窗口句柄,創(chuàng)建 GPU 加速的 OpenGL 環(huán)境,負責將整個渲染樹的內(nèi)容光柵化,直接將每一幀的內(nèi)容渲染合成到該窗口的 Surface 上并送顯。

IO線程:主要為了異步的文件 IO 讀寫,同時該線程會創(chuàng)建一個離屏的 GL 環(huán)境,這個環(huán)境和 GPU 線程的 GL 環(huán)境是同一個共享組,可以共享資源,圖片資源解碼的內(nèi)容可直接在該線程上傳生成 GPU 紋理,實現(xiàn)更高效的圖片渲染。

Javascript運行環(huán)境初始化

3.1 時序圖

9d28c008-47d2-11ec-b939-dac502259ad0.png

(點擊圖片查看高清大圖)

3.2 源碼解析

1.OnStart()

  • AceAbility繼承自Ability,當應用啟動時首先應用程序框架會調(diào)用AceAbility的生命周期函數(shù)OnStart();

  • 通過Ability的api獲取Hap包的路徑,通過讀取配置文件manifest.json獲取應用程序配置的前端的類型;

  • 當前我們只關(guān)注JS前端,目前支持的前端類型包括enum class FrontendType { JSON, JS, JS_CARD, DECLARATIVE_JS };

  • 根據(jù)前端類型調(diào)用ACE核心聚合類AceContainer的靜態(tài)方法CreateContainer,這個類是ACE框架平臺適配層的核心類,接下來的前端核心類和JS引擎的創(chuàng)建都是在其中完成的。

//foundationaceace_engineadapterpreviewentranceace_ability.cppvoid AceAbility::OnStart(const Want& want){    ...        //獲取打包的js bundle文件,取出配置文件,獲取前端類型    auto packagePathStr = GetBundleCodePath();    auto moduleInfo = GetHapModuleInfo();    if (moduleInfo != nullptr) {        packagePathStr += "/" + moduleInfo->name + "/";    }    FrontendType frontendType = GetFrontendTypeFromManifest(packagePathStr);
    // create container    //創(chuàng)建AceContainer:內(nèi)部初始化時創(chuàng)建了js線程,load了js engine,創(chuàng)建了JsFrontend    Platform::CreateContainer(        abilityId_, frontendType, this,        std::make_unique([this]() {            TerminateAbility();        }));    ...    ...
    //運行page    Platform::RunPage(        abilityId_, Platform::GetContainer(abilityId_)->GeneratePageId(),        parsedPageUrl, want.GetStringParam(START_PARAMS_KEY));
    ...}
2. CreateContainer
  • 在AceContainer::CreateContainer中,首先創(chuàng)建了AceContainer對象;

  • 在構(gòu)造函數(shù)中創(chuàng)建了FlutterTaskerExecutor對象用于多線程的任務管理;

  • 此處主要關(guān)注JS線程的創(chuàng)建和初始化,在InitJsThread()中創(chuàng)建了JS線程并獲取保存了jsRunner_用于JS任務的派發(fā);

//foundationaceace_engineadapterpreviewentranceace_container.cppvoid AceContainer::CreateContainer(int32_t instanceId, FrontendType type, AceAbility* aceAbility,    std::unique_ptr callback){    auto aceContainer = AceType::MakeRefPtr(instanceId, type, aceAbility, std::move(callback));    AceEngine::Get().AddContainer(instanceId, aceContainer);    auto front = aceContainer->GetFrontend();    if (front) {        front->UpdateState(Frontend::ON_CREATE);        front->SetJsMessageDispatcher(aceContainer);    }}
AceContainer::AceContainer(int32_t instanceId, FrontendType type, AceAbility* aceAbility,    std::unique_ptr callback) : instanceId_(instanceId), type_(type), aceAbility_(aceAbility){    ACE_DCHECK(callback);    //創(chuàng)建和初始化FlutterTaskerExecutor用于封裝管理Flutter ACE中涉及的多個線程:platform,UI,JS,GPU,IO,統(tǒng)一post任務到各線程執(zhí)行    auto flutterTaskExecutor = Referenced::MakeRefPtr();    //初始化platform線程,將flutter platform線程的TaskerRunner適配到ohos平臺主線程的EventRunner    flutterTaskExecutor->InitPlatformThread();    //初始化JS線程,這個線程用于解析JS,不歸flutter管理,因此是單獨在ACE里使用的    flutterTaskExecutor->InitJsThread();    //taskExector_封裝了所有線程任務調(diào)度的接口,因此會傳給Frontend用于JS前端解析任務和PipelineContext后端渲染UI和GPU IO相關(guān)    taskExecutor_ = flutterTaskExecutor;    if (type_ != FrontendType::DECLARATIVE_JS) {        //zll:初始化前端        InitializeFrontend();    }
    platformEventCallback_ = std::move(callback);}
void FlutterTaskExecutor::InitJsThread(bool newThread){    //創(chuàng)建并初始化JS線程,獲取保存js線程的TaskRunner    //JS線程是ACE平臺特有,不通過flutter創(chuàng)建管理    if (newThread) {        jsThread_ = std::make_unique(GenJsThreadName());        jsRunner_ = jsThread_->GetTaskRunner();    } else {        jsRunner_ = uiRunner_;    }}

3. JsFrontend

  • 完成JS線程的初始化后,如果前端類型不是DECLARATIVE_JS,會調(diào)用InitializeFrontend()對前端進行初始化。

  • 首先創(chuàng)建前端對象,F(xiàn)rontend::Create定義在js_frontend.cpp中,創(chuàng)建的是JsFrontend實例;

  • 然后通過JsEngineLoader::Get()動態(tài)加載QjsEngineLoader;

  • 再通過QjsEngineLoader創(chuàng)建QjsEngine并設置給JsFrontend;最后對JsFrontend對象做初始化;

  • JsFrontend是ACE框架從后端進入前端的唯一入口,AceAbility、AceContainer和JsFrontend是一一對應的關(guān)系;

//foundationaceace_engineadapterpreviewentranceace_container.cppvoid AceContainer::InitializeFrontend(){    if (type_ == FrontendType::JS) {        //目前Frontend::Create定義在js_frontend.cpp中,創(chuàng)建的是JsFrontend實例        frontend_ = Frontend::Create();        auto jsFrontend = AceType::DynamicCast(frontend_);        //創(chuàng)建并初始化js engine,此處是通過dlopen加載的qjs engine管理對象        jsFrontend->SetJsEngine(Framework::Get().CreateJsEngine(instanceId_));        ...    } else if (type_ == FrontendType::DECLARATIVE_JS) {        ...    } else {        ...    }    ACE_DCHECK(frontend_);    //初始化前端和js engine    frontend_->Initialize(type_, taskExecutor_);}
4. QjsEngine
  • 接下來我們繼續(xù)分析一下JS引擎管理對象的創(chuàng)建;

  • 首先通過dlopen動態(tài)加載libace_engine_qjs.z.so通過入口函數(shù)創(chuàng)建獲取QjsEngineLoader單例對象;

  • 然后通過QjsEngineLoader::CreateJsEngine()創(chuàng)建QjsEngine;

//foundationaceace_engineframeworksridgejs_frontendenginecommonjs_engine_loader.cpp//"libace_engine_qjs.z.so"動態(tài)庫的入口,在qjs_engine_loader.cpp中定義constexpr char JS_ENGINE_ENTRY[] = "OHOS_ACE_GetJsEngineLoader";constexpr char QUICK_JS_ENGINE_SHARED_LIB[] = "libace_engine_qjs.z.so";...const char* GetSharedLibrary(){    return QUICK_JS_ENGINE_SHARED_LIB;}JsEngineLoader& GetJsEngineLoader(const char* sharedLibrary){    void* handle = dlopen(sharedLibrary, RTLD_LAZY);    ...    //    auto loader = reinterpret_cast(entry());    ...
    return *loader;}...//通過加載動態(tài)鏈接庫的形式獲取qjs橋接模塊的入口函數(shù)并創(chuàng)建QjsEngineLoaderJsEngineLoader& JsEngineLoader::Get(){    static JsEngineLoader& instance = GetJsEngineLoader(GetSharedLibrary());    return instance;}
//foundationaceace_engineframeworksridgejs_frontendenginequickjsqjs_engine_loader.cppRefPtr QjsEngineLoader::CreateJsEngine(int32_t instanceId) const{    return AceType::MakeRefPtr(instanceId);}
5. JS線程
  • 在完成了QjsEngine的創(chuàng)建并設置給JsFrontend后,調(diào)用JsFrontend::Initialize();

  • 這里主要完成了FrontendDelegateImpl對象的創(chuàng)建和初始化將對JS引擎的相關(guān)操作委派給這個對象;

  • 以及Post JS引擎初始化的任務到JS線程的TaskRunner的message queue;

//foundationaceace_engineframeworksridgejs_frontendjs_frontend.cppbool JsFrontend::Initialize(FrontendType type, const RefPtr& taskExecutor){    LOGI("JsFrontend initialize begin.");    type_ = type;    ACE_DCHECK(type_ == FrontendType::JS);    //創(chuàng)建并初始化FrontendDelegate對象,具體實現(xiàn)為FrontendDelegateImpl    InitializeFrontendDelegate(taskExecutor);    //在JS線程初始化js engine,真正的啟動JS引擎運行時并創(chuàng)建上下文    taskExecutor->PostTask(        [weakEngine = WeakPtr(jsEngine_), delegate = delegate_] {            auto jsEngine = weakEngine.Upgrade();            if (!jsEngine) {                return;            }            jsEngine->Initialize(delegate);        },        TaskExecutor::JS);
    LOGI("JsFrontend initialize end.");    return true;}
6. jsframework
  • 在JS線程執(zhí)行QjsEngine對象的初始化,初始化JS運行環(huán)境;

  • 初始化JS引擎運行時上下文和初始化JavaScript框架層jsframework;

//foundationaceace_engineframeworksridgejs_frontendenginequickjsqjs_engine.cppbool QjsEngine::Initialize(const RefPtr& delegate){    ACE_SCOPED_TRACE("QjsEngine::Initialize");    LOGI("Initialize");
    JSRuntime* runtime = nullptr;    JSContext* context = nullptr;
    // put JS_NewContext as early as possible to make stack_top in context    // closer to the top stack frame pointer of JS thread.    runtime = JS_NewRuntime();    if (runtime != nullptr) {        context = JS_NewContext(runtime);    }
    ...
    engineInstance_ = AceType::MakeRefPtr(delegate, instanceId_);    return engineInstance_->InitJsEnv(runtime, context);}
bool QjsEngineInstance::InitJsEnv(JSRuntime* runtime, JSContext* context){    ...    context_ = context;    //1.初始化js運行時,上下文    if (!InitJsContext(context_, MAX_STACK_SIZE, instanceId_, this)) {        LOGE("Qjs cannot allocate JS context");        EventReport::JS_ENGINE_INIT_ERR);        JS_FreeRuntime(runtime_);        return false;    }    ...    //2.加載JS Framework,初始化JS前端框架    //加載jsframework,js_framework和js_framework_size是quickjs編譯器編譯jsframework的ts生成的c文件    //quickjs通過JS_ReadObject讀取生成的cbytecode,并通過JS_EvalFunction(ctx, obj)執(zhí)行相應的函數(shù)    //在這里最終調(diào)用的函數(shù)是jsframework/runtime/preparation/index.ts中的initFramework()函數(shù)    JSValue retVal = LoadJsFramework(GetQjsContext(), js_framework, js_framework_size, instanceId_);    bool result = JS_IsException(retVal) ? false : true;    if (context) {        JS_FreeValue(context, retVal);    }    ...
    return result;}
7. ACE模塊
  • 初始化JS引擎運行時上下文是在InitJsContext完成;

  • 其中初始化Ace模塊并將模塊導入JS運行時上下文中,為jsframework框架層提供了ACE功能相關(guān)的接口;

  • jsframework可以通過調(diào)用ACE模塊的接口完成Page上Dom元素到后端聲明式UI元素節(jié)點的創(chuàng)建;

  • 同時往JS運行時上下文全局對象掛載了日志打印的函數(shù)用于對接平臺日志打印功能;

//foundationaceace_engineframeworksridgejs_frontendenginequickjsqjs_engine.cpp//ace模塊向js context暴露的函數(shù),(js函數(shù)名,參數(shù)個數(shù),對應的C函數(shù))const JSCFunctionListEntry JS_ACE_FUNCS[] = {    JS_CFUNC_DEF_CPP("domCreateBody", 5, JsDomCreateBody),    JS_CFUNC_DEF_CPP("domAddElement", 9, JsDomAddElement),    JS_CFUNC_DEF_CPP("updateElementAttrs", 3, JsUpdateElementAttrs),    JS_CFUNC_DEF_CPP("updateElementStyles", 3, JsUpdateElementStyles),    JS_CFUNC_DEF_CPP("onCreateFinish", 0, JsOnCreateFinish),    JS_CFUNC_DEF_CPP("onUpdateFinish", 0, JsOnUpdateFinish),    JS_CFUNC_DEF_CPP("removeElement", 2, JsRemoveElement),    JS_CFUNC_DEF_CPP("callNative", 1, JsCallNative),    JS_CFUNC_DEF_CPP("callComponent", 3, JsCallComponent),    JS_CFUNC_DEF_CPP("loadIntl", 0, JsLoadIntl),    JS_CFUNC_DEF_CPP("loadLocaleData", 0, JsLoadLocaleData),#ifdef ENABLE_JS_DEBUG    JS_CFUNC_DEF_CPP("compileAndRunBundle", 4, JsCompileAndRunBundle),#endif};...
bool InitJsContext(JSContext* ctx, size_t maxStackSize, int32_t instanceId, const QjsEngineInstance* qjsEngineInstance){    ...        //將ace模塊注入到上下文中,使得jsframework可以通過注冊的接口調(diào)用ace的相關(guān)功能    // Inject ace native functions module    InitAceModules(ctx);
    JSValue globalObj, perfUtil;    globalObj = JS_GetGlobalObject(ctx);    perfUtil = JS_NewObject(ctx);
    InitJsConsoleObject(ctx, globalObj);
    JS_SetPropertyStr(ctx, perfUtil, "printlog", JS_NewCFunction(ctx, JsPerfPrint, "printlog", 0));    JS_SetPropertyStr(ctx, perfUtil, "sleep", JS_NewCFunction(ctx, JsPerfSleep, "sleep", 1));    JS_SetPropertyStr(ctx, perfUtil, "begin", JS_NewCFunction(ctx, JsPerfBegin, "begin", 1));    JS_SetPropertyStr(ctx, perfUtil, "end", JS_NewCFunction(ctx, JsPerfEnd, "end", 1));    JS_SetPropertyStr(ctx, globalObj, "perfutil", perfUtil);
    ...
    JSValue hiView;    hiView = JS_NewObject(ctx);    JS_SetPropertyStr(ctx, hiView, "report", JS_NewCFunction(ctx, JSHiViewReport, "report", 2));    JS_SetPropertyStr(ctx, globalObj, "hiView", hiView);
    JSValue i18nPluralRules;    i18nPluralRules = JS_NewObject(ctx);    JS_SetPropertyStr(ctx, i18nPluralRules, "select", JS_NewCFunction(ctx, JsPluralRulesFormat, "select", 1));    JS_SetPropertyStr(ctx, globalObj, "i18nPluralRules", i18nPluralRules);        //將ace模塊導入到cxt指定的js 上下文中    const char* str = "import * as ace from 'ace';
"                      "var global = globalThis;
"                      "global.ace = ace;
"#ifdef ENABLE_JS_DEBUG                      "global.compileAndRunBundle = ace.compileAndRunBundle;
"#endif                      "global.callNative = ace.callNative;
";
    if (JS_CALL_FAIL == CallEvalBuf(ctx, str, strlen(str), "", JS_EVAL_TYPE_MODULE, instanceId)) {        LOGW("Qjs created JS context but failed to init Ace modules!");    }
    JS_FreeValue(ctx, globalObj);    return true;}

8. 初始化完成

  • 完成JS運行時上下文初始化之后,緊接著加載初始化jsframework,為JS應用程序提供javascript應用框架;

  • 這個地方使用quickjs的運行bytecode的方法,在編譯時通過qjsc(quickjs編譯器)將jsframework編譯成c文件;

  • c文件的內(nèi)容就是一個bytecode的組數(shù)和數(shù)組大小,指定了jsframework的入口函數(shù);

  • 在這里對應jsframework/runtime/preparation/index.ts 中的initFramework()完成jsframework的初始化;

  • jsframework初始化完成的工作主要包括掛載到js運行時上下文全局對象上提供給native調(diào)用的jsframework函數(shù),注冊到jsframework的ACE提供的模塊及其中的方法和jsframework提供的與native一一對應的組件及其方法;

//foundationaceace_engineframeworksridgejs_frontendenginequickjsqjs_engine.cppJSValue LoadJsFramework(JSContext* ctx, const uint8_t buf[], const uint32_t bufSize, int32_t instanceId){    ACE_SCOPED_TRACE("LoadJsFramework");
    LOGI("Qjs loading JS framework");    //等同于調(diào)用jsframework/runtime/preparation/index.ts 中的initFramework()    JSValue ret = CallReadObject(ctx, buf, bufSize, true, instanceId);    if (JS_IsException(ret)) {        LOGD("Qjs loading JSFramework failed!");        QjsUtils::JsStdDumpErrorAce(ctx, JsErrorType::LOAD_JS_FRAMEWORK_ERROR, instanceId);    }
    return ret;}
//third_partyjsframework
untimepreparationinit.tsexport function initFramework(): void {  for (const serviceName in i18n) {    service.register(serviceName, i18n[serviceName]);  }  for (const serviceName in dpi) {    service.register(serviceName, dpi[serviceName]);  }  //jsframework提供的可供Ace native在QjsEngine對象中調(diào)用的TS方法  const globalMethods: GlobalInterface = {    'createInstance': globalApi.createInstance,    'registerModules': globalApi.registerModules,    'appDestroy': globalApi.appDestroy,    'appError': globalApi.appError,    'destroyInstance': globalApi.destroyInstance,    'getRoot': globalApi.getRoot,    'callJS': globalApi.callJS  };  //注冊modules,這些modules是ACE module提供的,調(diào)用這些模塊的方法,會通過調(diào)用注冊到qjs_engine的ace模塊中的callNative方法  //會最終通過ace module的callNative調(diào)用到qjs_engine中的JsCallNative-->JsHandleModule-->然后調(diào)用對應的native方法  // registerModules and registerComponents  ModulesInfo.forEach(modules => {    globalMethods['registerModules'](modules);  });    //注冊components組件,對組件方法的調(diào)用,最終會通過ace module的callComponent調(diào)用到qjs_engine中的JsCallComponent  ComponentsInfo.forEach((name) => {    if (name && name.type && name.methods) {      NativeElementClassFactory.createNativeElementClass(        name.type,        name.methods      );    }  });  //全局方法,這些方法可以被Qjs engine通過JS_GetPropertyStr(ctx, globalObj, "methodNamge")獲取并調(diào)用,從而實現(xiàn)了從native到js的調(diào)用  for (const methodName in globalMethods) {    global[methodName] = (...args: any) => {      const res: any = globalMethods[methodName](...args);      if (res instanceof Error) {        Log.error(res.toString());      }      return res;    };  }}

總結(jié)

以上內(nèi)容首先對 OpenHarmony 標準系統(tǒng)上 JS UI 框架引擎 ACE 的邏輯架構(gòu)及相關(guān)模塊進行了簡單的介紹,給出了 ACE 架構(gòu)中相關(guān)模塊涉及的部分類的類圖,結(jié)合本次重點分析的 Javascript 運行環(huán)境初始化的時序圖詳細分析了 Javascript 運行環(huán)境初始化的整個流程。

本文首發(fā)自:https://harmonyos.51cto.com/posts/7908
編輯:jq


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JS
    JS
    +關(guān)注

    關(guān)注

    0

    文章

    80

    瀏覽量

    19092
  • ui
    ui
    +關(guān)注

    關(guān)注

    0

    文章

    211

    瀏覽量

    22461
  • OpenHarmony
    +關(guān)注

    關(guān)注

    33

    文章

    3974

    瀏覽量

    21346

原文標題:OpenHarmony源碼解析之ACE(JavaScript運行環(huán)境初始化)

文章出處:【微信號:gh_e4f28cfa3159,微信公眾號:OpenAtom OpenHarmony】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    ELF-RV112B RKNN模型加載與運行初始化

    ELF-RV112B RKNN模型加載與運行初始化
    的頭像 發(fā)表于 04-03 16:08 ?155次閱讀
    ELF-RV112B RKNN模型加載與<b class='flag-5'>運行</b>時<b class='flag-5'>初始化</b>

    PC強實時運動控制(一):C#的EtherCAT總線初始化(下)

    通過使用配置工具導出ZAR文件進行EtherCAT總線初始化
    的頭像 發(fā)表于 02-05 10:00 ?2216次閱讀
    PC強實時運動控制(一):C#的EtherCAT總線<b class='flag-5'>初始化</b>(下)

    MCU工程初始化,到底該不該交給工具?

    背景 工程初始化重復性高,但出錯成本大。工程師常問:交給工具是不是會丟失掌控? 工具可做的事 時鐘樹、引腳復用、外設配置 工程生成、代碼模板套用 參數(shù)校驗和約束檢查 工程師仍需做的事 特殊業(yè)務邏輯
    的頭像 發(fā)表于 01-29 10:18 ?246次閱讀
    MCU工程<b class='flag-5'>初始化</b>,到底該不該交給工具?

    EtherCAT總線初始化步驟

    EtherCAT(Ethernet for Control Automation Technology)是一種高性能的工業(yè)以太網(wǎng)通信協(xié)議,廣泛應用于工業(yè)自動領(lǐng)域。其初始化過程是確保系統(tǒng)穩(wěn)定運行
    的頭像 發(fā)表于 12-22 10:10 ?930次閱讀
    EtherCAT總線<b class='flag-5'>初始化</b>步驟

    瀚海微SD NAND TF卡硬件識別與初始化類問題探討

    在瀚海微SD NAND/TF卡的實際應用中,硬件識別與初始化是保障設備正常運行的首要環(huán)節(jié),該環(huán)節(jié)出現(xiàn)故障會直接導致存儲卡無法投入使用,尤其在工業(yè)控制、車載設備等關(guān)鍵場景中,可能引發(fā)設備停機、數(shù)據(jù)丟失
    的頭像 發(fā)表于 11-18 09:58 ?782次閱讀
    瀚海微SD NAND  TF卡硬件識別與<b class='flag-5'>初始化</b>類問題探討

    串口通信基石:Air8000下Modbus RTU串口初始化詳解!

    串口初始化是Modbus RTU通信穩(wěn)定可靠的關(guān)鍵起點。本篇深入剖析Air8000開發(fā)板串口參數(shù)配置、初始化代碼實現(xiàn)及調(diào)試要點,結(jié)合master_rtu示例,分享實際操作中的經(jīng)驗與避坑指南,讓您
    的頭像 發(fā)表于 10-28 16:33 ?1778次閱讀
    串口通信基石:Air8000下Modbus RTU串口<b class='flag-5'>初始化</b>詳解!

    NVMe高速傳輸擺脫XDMA設計33:初始化功能驗證與分析

    本文主要交流NVMe設計思路,在本博客已給出相關(guān)博文五十多篇,希望對初學者有一定作用 初始化功能主要實現(xiàn) PCIe 鏈路設備的初始化配置和 NVMe 初始化配置。 復雜的PCIe 事務交互與設備行為
    發(fā)表于 10-08 08:02

    GraniStudio:IO初始化以及IO資源配置例程

    1.文件運行 導入工程 雙擊運行桌面GraniStudio.exe。 通過引導界面導入IO初始化以及IO資源配置例程,點擊導入按鈕。 打開IO初始化以及IO資源配置例程所在路徑,選中I
    的頭像 發(fā)表于 08-22 17:34 ?1049次閱讀
    GraniStudio:IO<b class='flag-5'>初始化</b>以及IO資源配置例程

    GraniStudio:初始化例程

    1.文件運行 導入工程 雙擊運行桌面GraniStudio.exe。 通過引導界面導入初始化例程,點擊導入按鈕。 打開初始化例程所在路徑,選中初始化
    的頭像 發(fā)表于 08-22 16:45 ?1032次閱讀
    GraniStudio:<b class='flag-5'>初始化</b>例程

    MCU外設初始化:為什么參數(shù)配置必須優(yōu)先于使能

    在微控制器領(lǐng)域,初始化參數(shù)配置階段至關(guān)重要。此時,雖無電源驅(qū)動,但微控制器在使能信號到來前,借初始化參數(shù)配置這一精細步驟,開啟關(guān)鍵準備進程。初始化參數(shù)配置如同物理坐標錨定、邏輯指令部署、內(nèi)在秩序預設
    的頭像 發(fā)表于 08-13 10:38 ?951次閱讀

    定義IO初始化結(jié)構(gòu)體

    由上述IOPORT相關(guān)功能的枚舉類型我們可以知道,在對IOPORT模塊進行初始化時需要根據(jù)情況配置它們。因此我們定義一個IOPORT初始化的結(jié)構(gòu)體類型IOPORT_Init_t,它的成員包括了由上述所有枚舉類型所聲明的變量,因此該結(jié)構(gòu)體類型的變量可以包含IOPORT的相關(guān)
    的頭像 發(fā)表于 07-16 16:26 ?1560次閱讀

    NVMe高速傳輸擺脫XDMA設計十:NVMe初始化狀態(tài)機設計

    在完成PCIe配置初始化后,PCIe總線域的地址空間都分配完畢,可以執(zhí)行傳出存儲讀寫TLP,系統(tǒng)初始化進入NVMe配置初始化。NVMe配置初始化主要完成NVMe設備BAR空間的NVMe
    發(fā)表于 07-05 22:03

    NVMe高速傳輸擺脫XDMA設計七:系統(tǒng)初始化

    直接采用PCIe實現(xiàn)NVMe功能,它的系統(tǒng)初始化流程主要分為鏈路訓練、PCIe 初始化和 NVMe 初始化, 分別實現(xiàn) PCIe鏈路連接、 PCIe 設備枚舉配置和 NVMe 設備配置功能。 其中鏈
    發(fā)表于 07-04 09:14

    IM系列設備過載故障:界面初始化終止的診斷流程與修復指南

    當 IM 系列設備出現(xiàn)過載故障導致界面初始化終止時,通常表現(xiàn)為設備啟動后操作界面無顯示、指示燈異常閃爍或初始化進度條停滯不前,同時可能伴隨設備運行異響或異常發(fā)熱。初步判斷時,可觀察設備是否有錯
    的頭像 發(fā)表于 06-28 09:47 ?1368次閱讀

    IM 系列設備過載保護機制下界面初始化中斷的底層邏輯與解決方案

    一、過載保護機制與界面初始化的關(guān)聯(lián)基礎(chǔ) IM 系列設備的過載保護機制是保障設備安全運行的核心功能,其通過傳感器實時采集設備運行參數(shù),如電流、電壓、溫度、系統(tǒng)資源占用率等。一旦這些參數(shù)超出預設閾值
    的頭像 發(fā)表于 06-27 09:58 ?679次閱讀