赞
踩
Ability是系统调度应用的最小单元,通过JS引擎隔离开发者代码。其中,每个Ability都有自己的UI线程,实现并行渲染。
std::call_once(onceFlag, [abilityContext, cacheDir]() { LOGI("Initialize for current process."); SetHwIcuDirectory(); Container::UpdateCurrent(INSTANCE_ID_PLATFORM); CapabilityRegistry::Register(); AceApplicationInfo::GetInstance().SetPackageName(abilityContext->GetBundleName()); AceApplicationInfo::GetInstance().SetDataFileDirPath(abilityContext->GetFilesDir()); AceApplicationInfo::GetInstance().SetApiTargetVersion(abilityContext->GetApplicationInfo()->apiTargetVersion); AceApplicationInfo::GetInstance().SetAppVersionName(abilityContext->GetApplicationInfo()->versionName); AceApplicationInfo::GetInstance().SetAppVersionCode(abilityContext->GetApplicationInfo()->versionCode); AceApplicationInfo::GetInstance().SetUid(IPCSkeleton::GetCallingUid()); AceApplicationInfo::GetInstance().SetPid(IPCSkeleton::GetCallingPid()); ImageCache::SetImageCacheFilePath(cacheDir); ImageCache::SetCacheFileInfo(); AceEngine::InitJsDumpHeadSignal(); });
window->RegisterWindowChangeListener(aceWindowListener);
// register drag event callback
window->RegisterDragListener(aceWindowListener);
// register Occupied Area callback
window->RegisterOccupiedAreaChangeListener(aceWindowListener);
// register ace ability handler callback
window->SetAceAbilityHandler(aceWindowListener);
// register input consumer callback
std::shared_ptr<AceWindowListener> aceInputConsumer = std::make_shared<AceWindowListener>(self);
window->SetInputEventConsumer(aceInputConsumer);
auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
auto resourceManager = GetResourceManager();
auto packagePathStr = GetBundleCodePath();
auto moduleInfo = GetHapModuleInfo();
ace_ability.cpp
Platform::AceContainer::CreateContainer(abilityId_, frontendType, srcPath, shared_from_this(),
std::make_unique<AcePlatformEventCallback>([this]() { TerminateAbility(); },
[this](const std::string& address) {
AAFwk::Want want;
want.AddEntity(Want::ENTITY_BROWSER);
want.SetUri(address);
want.SetAction(ACTION_VIEWDATA);
this->StartAbility(want);
}),
false, useNewPipe);
AceEngine::Get().AddContainer(instanceId, aceContainer);
ace_ability.cpp
Platform::AceContainer::SetView(aceView, density_, 0, 0, window, callback);
ace_ability.cpp
在Ability初始化后便开始进行
auto apiCompatibleVersion = abilityContext->GetApplicationInfo()->apiCompatibleVersion;
auto apiReleaseType = abilityContext->GetApplicationInfo()->apiReleaseType;
auto apiTargetVersion = abilityContext->GetApplicationInfo()->apiTargetVersion;
auto useNewPipe = AceNewPipeJudgement::QueryAceNewPipeEnabledFA(
AceApplicationInfo::GetInstance().GetPackageName(), apiCompatibleVersion, apiTargetVersion, apiReleaseType);
LOGI("AceAbility: apiCompatibleVersion: %{public}d, apiTargetVersion: %{public}d, and apiReleaseType: %{public}s, "
"useNewPipe: %{public}d",
apiCompatibleVersion, apiTargetVersion, apiReleaseType.c_str(), useNewPipe);
之后在ace_container.cpp中将其置为true,开始使用
//ace_container.cpp
if (useNewPipeline) {
SetUseNewPipeline();
}
//container.h
void SetUseNewPipeline()
{
useNewPipeline_ = true;
}
ace_container.cpp
RefPtr<NG::FrameNode> rootNode = context->GetRootElement();
rootNode->UpdateConfigurationUpdate(configurationChange);
原始文件
@Entry
@Component
struct Index {
@State message: string = 'Hello World'
build() {
Stack() {
}.width('80%').height('80%')
.backgroundColor('#fff111')
}
}
使用IDE编译后待执行文件(entry/build/default/intermediates/assets/default/js/MainAbility/pages/index.js)
var _ff3b25f72d479da6a3314472b8401bae; /******/ (() => { // webpackBootstrap var __webpack_exports__ = {}; /*!*******************************************************************************************************************!*\ !*** ../../../../../../DevEcoStudioProjects/MyApplication17/entry/src/main/ets/MainAbility/pages/index.ets?entry ***! \*******************************************************************************************************************/ class Index extends View { constructor(compilerAssignedUniqueChildId, parent, params) { super(compilerAssignedUniqueChildId, parent); this.__message = new ObservedPropertySimple('Hello World', this, "message"); this.updateWithValueParams(params); } updateWithValueParams(params) { if (params.message !== undefined) { this.message = params.message; } } aboutToBeDeleted() { this.__message.aboutToBeDeleted(); SubscriberManager.Get().delete(this.id()); } get message() { return this.__message.get(); } set message(newValue) { this.__message.set(newValue); } render() { Stack.create(); Stack.width('80%'); Stack.height('80%'); Stack.backgroundColor('#fff111'); Stack.pop(); } } loadDocument(new Index("1", undefined, {})); _ff3b25f72d479da6a3314472b8401bae = __webpack_exports__; /******/ })() ; //# sourceMappingURL=index.js.map
执行JS页面文件时,会执行上面的全局方法loadDocument,在loadDocument函数中会创建相应的UI对象进行渲染加载。
void JsRegisterViews(BindingTarget globalObj) { auto runtime = std::static_pointer_cast<ArkJSRuntime>(JsiDeclarativeEngineInstance::GetCurrentRuntime()); if (!runtime) { LOGE("JsRegisterViews can't find runtime"); } auto vm = runtime->GetEcmaVm(); globalObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "loadDocument"), panda::FunctionRef::New(const_cast<panda::EcmaVM*>(vm), JsLoadDocument)); ... } panda::Local<panda::JSValueRef> JsLoadDocument(panda::JsiRuntimeCallInfo *runtimeCallInfo) { LOGI("Load Document start"); ... JSView* view = static_cast<JSView*>(obj->GetNativePointerField(0)); ... if (Container::IsCurrentUseNewPipeline()) { auto pageRootNode = view->CreateNode(); page->SetRootNode(pageRootNode); } ... }
在执行JsLoadDocument方法时,入参为new Index(“1”, undefined, {})对象,该对象由于在C++侧注入了基类的定义,会走ConstructorCallback回调,生成JSView的对象并保存Render方法,JSView* view = static_cast<JSView*>(obj->GetNativePointerField(0))调用在通过JS引擎的能力从对象中获取我们生成的JSView对象,并调用JSView的对象创建page节点。
void JSView::JSBind(BindingTarget object) { JSClass<JSView>::Declare("NativeView"); ... JSClass<JSView>::Inherit<JSViewAbstract>(); JSClass<JSView>::Bind(object, ConstructorCallback, DestructorCallback); } void JSView::ConstructorCallback(const JSCallbackInfo& info) { JSRef<JSObject> thisObj = info.This(); JSRef<JSVal> renderFunc = thisObj->GetProperty("render"); if (!renderFunc->IsFunction()) { LOGE("View derived classes must provide render(){...} function"); JSException::Throw("%s", "View derived classes must provide render(){...} function"); return; } int argc = info.Length(); if (argc > 1 && (info[0]->IsNumber() || info[0]->IsString())) { std::string viewId = info[0]->ToString(); auto instance = AceType::MakeRefPtr<JSView>(viewId, info.This(), JSRef<JSFunc>::Cast(renderFunc)); ... LOGD("JSView ConstructorCallback: %{public}s", instance->id_.c_str()); } else { LOGE("JSView creation with invalid arguments."); JSException::Throw("%s", "JSView creation with invalid arguments."); } }
内部Render方法(RefPtrNG::FrameNode JSView::CreateNode())会在页面布局加载时进行对应,而这些JS的静态方法,包括: Stack.create();Stack.width(‘80%’);Stack.height(‘80%’);Stack.backgroundColor(‘#fff111’);Stack.pop(),在C++侧通过JS引擎注入定义,在执行JS代码时会分别走到对应的C++侧绑定方法来生成节点并设置属性。
void JSStack::JSBind(BindingTarget globalObj)
{
JSClass<JSStack>::Declare("Stack");
MethodOptions opt = MethodOptions::NONE;
JSClass<JSStack>::StaticMethod("create", &JSStack::Create, opt);
...
JSClass<JSStack>::StaticMethod("width", SetWidth);
JSClass<JSStack>::StaticMethod("height", SetHeight);
...
JSClass<JSStack>::Bind<>(globalObj);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。