前言:
现时大家对“js绑定不上初始化属性”可能比较注重,你们都需要分析一些“js绑定不上初始化属性”的相关知识。那么小编同时在网络上搜集了一些关于“js绑定不上初始化属性””的相关知识,希望你们能喜欢,朋友们快快来学习一下吧!深入理解 ArkUI - 框架初始化从Stage模型说起
Stage模型应用程序中的 UIAbility 实例会以不同的状态传输。UIAbility 类提供一系列回调。通过这些回调,可以了解 UIAbility 实例的状态变化。
UIAbility的生命周期有创建、前台、后台、销毁四种状态
UIAbility实例创建完成后,在进入Foreground状态之前,系统会创建一个WindowStage实例,并触发onWindowStageCreate回调。您可以在回调中设置 UI 加载和 WindowStage 事件订阅。
使用DevEco创建简单Demo,src/main/ets/entryability/EntryAbility.ts代码中定义了onWindowStageCreate函数
export default class EntryAbility extends UIAbility { ... onWindowStageCreate(windowStage: window.WindowStage) { // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); }); } ...}
启动过程UIAbility::OnForeground过程中会创建AppWindowStage,回调onWindowStageCreate函数,通过windowStage.loadContent函数完成ArkUI初始化和页面加载。
loadContent函数实现在文件foundation/window/window_manager/interfaces/kits/napi/window_runtime/window_stage_napi/js_window_stage.cpp中
napi_value JsWindowStage::OnLoadContent(napi_env env, napi_callback_info info, bool isLoadedByName){ ... // 创建LoadContentTask异步Napi任务 NapiAsyncTask::CompleteCallback complete = [weak = windowScene_, contentStorage, contextUrl, isLoadedByName]( napi_env env, NapiAsyncTask& task, int32_t status) { auto weakScene = weak.lock(); sptr<Window> win = weakScene ? weakScene->GetMainWindow() : nullptr; if (win == nullptr) { task.Reject(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY))); WLOGFE("[NAPI]Get window failed"); return; } LoadContentTask(contentStorage, contextUrl, win, env, task, isLoadedByName); }; napi_value result = nullptr; NapiAsyncTask::Schedule("JsWindowStage::OnLoadContent", env, CreateAsyncTaskWithLastParam(env, callBack, nullptr, std::move(complete), &result)); return result;}
在LoadContentTask中创建UiContent并初始化ArkUI框架。
WMError WindowSessionImpl::SetUIContentInner(const std::string& contentInfo, napi_env env, napi_value storage, WindowSetUIContentType type, AppExecFwk::Ability* ability){ ... switch (type) { default: case WindowSetUIContentType::DEFAULT: aceRet = uiContent->Initialize(this, contentInfo, storage); break; ... } ...}初始化
整个流程图如下所示:
涉及到数据结构如下所示:
Container初始化
如时序图Container初始化所示
1. AceContainer::CreateContainer创建AceContainer对象,并在构造函数完成JS线程的创建保存在jsEunner_中
2. 创建JsFrontend对象,作为ArkUI框架从后端到前端的唯一入口,与AceAbility、AceCntainer一一对应。
3. 当前主要是响应式框架,根据类型FrontendType::DECLARATIVE_JS创建DeclarativeFrontendNG
4. 动态创建jsEngine与declarativeFrontend绑定
Pipeline初始化
如时序图Pipeline初始化所示
VSync注册
AceContainer::SetView函数会创建RosenWindow,构造函数如下:
RosenWindow::RosenWindow(const OHOS::sptr<OHOS::Rosen::Window>& window, RefPtr<TaskExecutor> taskExecutor, int32_t id) : rsWindow_(window), taskExecutor_(taskExecutor), id_(id){ vsyncCallback_ = std::make_shared<OHOS::Rosen::VsyncCallback>(); vsyncCallback_->onCallback = [weakTask = taskExecutor_, id = id_](int64_t timeStampNanos, int64_t frameCount) { auto taskExecutor = weakTask.Upgrade(); auto onVsync = [id, timeStampNanos, frameCount] { int64_t ts = GetSysTimestamp(); ArkUIPerfMonitor::GetInstance().StartPerf(); if (FrameReport::GetInstance().GetEnable()) { FrameReport::GetInstance().FlushBegin(); } ContainerScope scope(id); // use container to get window can make sure the window is valid auto container = Container::Current(); CHECK_NULL_VOID(container); auto window = container->GetWindow(); CHECK_NULL_VOID(window); int64_t refreshPeriod = window->GetVSyncPeriod(); window->OnVsync(static_cast<uint64_t>(timeStampNanos), static_cast<uint64_t>(frameCount)); ArkUIPerfMonitor::GetInstance().FinishPerf(); auto pipeline = container->GetPipelineContext(); CHECK_NULL_VOID(pipeline); pipeline->OnIdle(std::min(ts, timeStampNanos) + refreshPeriod); JankFrameReport::GetInstance().JankFrameRecord(timeStampNanos, window->GetWindowName()); if (FrameReport::GetInstance().GetEnable()) { FrameReport::GetInstance().FlushEnd(); } window->SetLastVsyncEndTimestamp(GetSysTimestamp()); }; auto uiTaskRunner = SingleTaskExecutor::Make(taskExecutor, TaskExecutor::TaskType::UI); if (uiTaskRunner.IsRunOnCurrentThread()) { onVsync(); return; } uiTaskRunner.PostTask([callback = std::move(onVsync)]() { callback(); }, "ArkUIRosenWindowVsync"); }; rsUIDirector_ = OHOS::Rosen::RSUIDirector::Create(); if (window->GetSurfaceNode()) { rsUIDirector_->SetRSSurfaceNode(window->GetSurfaceNode()); } rsUIDirector_->SetCacheDir(AceApplicationInfo::GetInstance().GetDataFileDirPath()); rsUIDirector_->Init(); rsUIDirector_->SetUITaskRunner( [taskExecutor, id](const std::function<void()>& task, uint32_t delay) { ContainerScope scope(id); CHECK_NULL_VOID(taskExecutor); taskExecutor->PostDelayedTask( task, TaskExecutor::TaskType::UI, delay, "ArkUIRosenWindowRenderServiceTask", PriorityType::HIGH); }, id); rsUIDirector_->SetRequestVsyncCallback([weak = weak_from_this()]() { auto self = weak.lock(); CHECK_NULL_VOID(self); self->RequestFrame(); });}
vsyncCallback_就是ArkUI收到Vsync信号后要执行的逻辑:1. window->OnVsync(渲染管线执行)2.pipeline->OnIdle
ArkUI通过函数rsWindow_->RequestVsync(vsyncCallback_)向RS注册Vsync。下次Vsync信号到来时,RS通过此vsyncCallback_分发执行任务
Index页面加载
如时序图Page加载所示先创建Index页面,再OnPageReady中执行Build函数,创建页面组件。最终完成页面的加载
组件树创建
void AceContainer::AttachView( std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height){ ... taskExecutor_->PostTask( [weak]() { auto context = weak.Upgrade(); if (context == nullptr) { return; } context->SetupRootElement(); }, TaskExecutor::TaskType::UI); aceView_->Launch(); ...}
void AceContainer::AttachView( std::shared_ptr<Window> window, AceViewPreview* view, double density, int32_t width, int32_t height){ ... taskExecutor_->PostTask( [weak]() { auto context = weak.Upgrade(); if (context == nullptr) { return; } context->SetupRootElement(); }, TaskExecutor::TaskType::UI); aceView_->Launch(); ...}1. stageNode挂载在rootNode_中
void PipelineContext::SetupRootElement(){ CHECK_RUN_ON(UI); rootNode_ = FrameNode::CreateFrameNodeWithTree( V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>()); ... auto stageNode = FrameNode::CreateFrameNode( V2::STAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<StagePattern>()); ... if (windowModal_ == WindowModal::CONTAINER_MODAL) { ACE_SCOPED_TRACE("WindowModal::CONTAINER_MODAL"); MaximizeMode maximizeMode = GetWindowManager()->GetWindowMaximizeMode(); rootNode_->AddChild( ContainerModalViewFactory::GetView(atomicService ? atomicService : stageNode, maximizeMode)); } else { rootNode_->AddChild(atomicService ? atomicService : stageNode); } stageManager_ = MakeRefPtr<StageManager>(stageNode); //保存在stageManager_}1. pageNode挂载在stageNode中
void PageRouterManager::LoadPage(int32_t pageId, const RouterPageInfo& target, bool needHideLast, bool needTransition){ ... auto pageNode = FrameNode::CreateFrameNode(V2::PAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), pagePattern); ... // loadNamedRouter_ == JsiDeclarativeEngine::LoadNamedRouterSource auto result = loadNamedRouter_(target.url, target.isNamedRouterMode); ... if (!OnPageReady(pageNode, needHideLast, needTransition)) { pageRouterStack_.pop_back(); LOGE("LoadPage OnPageReady Failed"); return; } ...}bool PageRouterManager::OnPageReady( const RefPtr<FrameNode>& pageNode, bool needHideLast, bool needTransition, bool isCardRouter, int64_t cardId){ ... auto context = DynamicCast<NG::PipelineContext>(pipeline); auto stageManager = context ? context->GetStageManager() : nullptr; //取出stageNode if (stageManager) { return stageManager->PushPage(pageNode, needHideLast, needTransition); } return false;}1. pageRootNode(Index组件)挂载在pageNode中
bool JsiDeclarativeEngine::LoadNamedRouterSource(const std::string& namedRoute, bool isTriggeredByJs){ ... // 执行 new Index() 创建View auto ret = iter->second.pageGenerator->Call(vm, JSNApi::GetGlobalObject(vm), argv.data(), 0); if (!ret->IsObject()) { return false; } // view 挂载到 pageNode 中 Framework::UpdateRootComponent(ret->ToObject(vm)); JSViewStackProcessor::JsStopGetAccessRecording(); return true;}
最终执行到UpdateRootComponent函数中将pageRootNode添加到pageNode中
void UpdateRootComponent(const panda::Local<panda::ObjectRef>& obj){ ACE_FUNCTION_TRACE(); auto* view = static_cast<JSView*>(obj->GetNativePointerField(0)); ... { auto frontEnd = AceType::DynamicCast<DeclarativeFrontendNG>(container->GetFrontend()); CHECK_NULL_VOID(frontEnd); auto pageRouterManager = frontEnd->GetPageRouterManager(); CHECK_NULL_VOID(pageRouterManager); pageNode = pageRouterManager->GetCurrentPageNode(); CHECK_NULL_VOID(pageNode); } auto pageRootNode = AceType::DynamicCast<NG::UINode>(view->CreateViewNode()); CHECK_NULL_VOID(pageRootNode); // root custom component pageRootNode->MountToParent(pageNode); ... }
最终生成组件树
标签: #js绑定不上初始化属性