ArkUI实现
编译期
1.通过声明式语法使用系统和自定义组件描述UI树
2.将装饰器修饰的 UI 组件树,转换成 ViewPU 树
运行时
1.监听并响应系统硬件的VSync信号
2.在测量和布局阶段,通过上面的ViewPU树进一步构建 FrameNode 树 和 RSNode 树
3.在布局和绘制阶段,通过 RSNode 录制绘制命令,然后使用IPC 发送命令到 RenderService 进程中,由RenderService完成 UI 绘制
转换前的代码
import { BasicDataSource } from './BasicDataSource';
class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
@Entry
@Component
struct Index {
@State message1: string = 'hello'
message2: string = 'Hi'
@State showMode: number = 0
private data: MyDataSource = new MyDataSource();
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(`Hello ${i}`)
}
}
build() {
Column() {
Row() {
Column() {
Text('the first text')
.fontSize(50)
.fontWeight(FontWeight.Bold)
Text('the second text')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
Row() {
Column() {
Text('the third text')
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
List({ space: 3 }) {
LazyForEach(this.data, (item: string) => {
ListItem() {
Row() {
Text(item).fontSize(50)
.onAppear(() => {
console.info("appear:" + item)
})
}.margin({ left: 10, right: 10 })
}
}, (item: string) => item)
}.cachedCount(5)
ForEach([1, 2, 3], (item: number, index: number) => {
Text(`item: ${item} index: ${index}`)
.fontSize(50)
.fontWeight(FontWeight.Bold
)
})
if (this.showMode === 0) {
Child({
message1: this.message1,
message2: this.message2
})
} else if (this.showMode === 1) {
Child2()
} else {
Text("this is if else else branch")
}
}
}
}
@Component
struct Child {
@Link message1: string;
@Prop message2: string;
build() {
Column() {
Text(this.message1)
}
}
}
@Component
struct Child2 {
private message: string = 'Hello';
build() {
Column() {
Text(this.message)
}
}
}
转换成TS后的代码
if (!("finalizeConstruction" in ViewPU.prototype)) {
Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { });
}
interface Child2_Params {
message?: string;
}
interface Child_Params {
message1?: string;
message2?: string;
}
interface Index_Params {
message1?: string;
message2?: string;
showMode?: number;
data?: MyDataSource;
}
import { BasicDataSource } from "@bundle:com.unravel.myapplication/entry/ets/pages/BasicDataSource";
class MyDataSource extends BasicDataSource {
private dataArray: string[] = [];
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): string {
return this.dataArray[index];
}
public addData(index: number, data: string): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}
public pushData(data: string): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}
}
class Index extends ViewPU {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) {
super(parent, __localStorage, elmtId, extraInfo);
if (typeof paramsLambda === "function") {
this.paramsGenerator_ = paramsLambda;
}
this.__message1 = new ObservedPropertySimplePU('hello', this, "message1");
this.message2 = 'Hi';
this.__showMode = new ObservedPropertySimplePU(0, this, "showMode");
this.data = new MyDataSource();
this.setInitiallyProvidedValue(params);
this.finalizeConstruction();
}
setInitiallyProvidedValue(params: Index_Params) {
if (params.message1 !== undefined) {
this.message1 = params.message1;
}
if (params.message2 !== undefined) {
this.message2 = params.message2;
}
if (params.showMode !== undefined) {
this.showMode = params.showMode;
}
if (params.data !== undefined) {
this.data = params.data;
}
}
updateStateVars(params: Index_Params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__message1.purgeDependencyOnElmtId(rmElmtId);
this.__showMode.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__message1.aboutToBeDeleted();
this.__showMode.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
private __message1: ObservedPropertySimplePU<string>;
get message1() {
return this.__message1.get();
}
set message1(newValue: string) {
this.__message1.set(newValue);
}
private message2: string;
private __showMode: ObservedPropertySimplePU<number>;
get showMode() {
return this.__showMode.get();
}
set showMode(newValue: number) {
this.__showMode.set(newValue);
}
private data: MyDataSource;
aboutToAppear() {
for (let i = 0; i <= 20; i++) {
this.data.pushData(`Hello ${i}`);
}
}
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Row.create();
}, Row);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('the first text');
Text.fontSize(50);
Text.fontWeight(FontWeight.Bold);
}, Text);
Text.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('the second text');
Text.fontSize(50);
Text.fontWeight(FontWeight.Bold);
}, Text);
Text.pop();
Column.pop();
Row.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
Row.create();
}, Row);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create('the third text');
Text.fontSize(50);
Text.fontWeight(FontWeight.Bold);
}, Text);
Text.pop();
Column.pop();
Row.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
List.create({ space: 3 });
List.cachedCount(5);
}, List);
{
const __lazyForEachItemGenFunction = _item => {
const item = _item;
{
const itemCreation2 = (elmtId, isInitialRender) => {
ListItem.create(() => { }, false);
};
const observedDeepRender = () => {
this.observeComponentCreation2(itemCreation2, ListItem);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Row.create();
Row.margin({ left: 10, right: 10 });
}, Row);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(item);
Text.fontSize(50);
Text.onAppear(() => {
console.info("appear:" + item);
});
}, Text);
Text.pop();
Row.pop();
ListItem.pop();
};
observedDeepRender();
}
};
const __lazyForEachItemIdFunc = (item: string) => item;
LazyForEach.create("1", this, this.data, __lazyForEachItemGenFunction, __lazyForEachItemIdFunc);
LazyForEach.pop();
}
List.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
ForEach.create();
const forEachItemGenFunction = (_item, index: number) => {
const item = _item;
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(`item: ${item} index: ${index}`);
Text.fontSize(50);
Text.fontWeight(FontWeight.Bold);
}, Text);
Text.pop();
};
this.forEachUpdateFunction(elmtId, [1, 2, 3], forEachItemGenFunction, undefined, true, false);
}, ForEach);
ForEach.pop();
this.observeComponentCreation2((elmtId, isInitialRender) => {
If.create();
if (this.showMode === 0) {
this.ifElseBranchUpdateFunction(0, () => {
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new Child(this, {
message1: this.__message1,
message2: this.message2
}, undefined, elmtId, () => { }, { page: "entry/src/main/ets/pages/Index.ets", line: 81 });
ViewPU.create(componentCall);
let paramsLambda = () => {
return {
message1: this.message1,
message2: this.message2
};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {
message2: this.message2
});
}
}, { name: "Child" });
}
});
}
else if (this.showMode === 1) {
this.ifElseBranchUpdateFunction(1, () => {
{
this.observeComponentCreation2((elmtId, isInitialRender) => {
if (isInitialRender) {
let componentCall = new Child2(this, {}, undefined, elmtId, () => { }, { page: "entry/src/main/ets/pages/Index.ets", line: 86 });
ViewPU.create(componentCall);
let paramsLambda = () => {
return {};
};
componentCall.paramsGenerator_ = paramsLambda;
}
else {
this.updateStateVarsOfChildByElmtId(elmtId, {});
}
}, { name: "Child2" });
}
});
}
else {
this.ifElseBranchUpdateFunction(2, () => {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create("this is if else else branch");
}, Text);
Text.pop();
});
}
}, If);
If.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
static getEntryName(): string {
return "Index";
}
}
class Child extends ViewPU {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) {
super(parent, __localStorage, elmtId, extraInfo);
if (typeof paramsLambda === "function") {
this.paramsGenerator_ = paramsLambda;
}
this.__message1 = new SynchedPropertySimpleTwoWayPU(params.message1, this, "message1");
this.__message2 = new SynchedPropertySimpleOneWayPU(params.message2, this, "message2");
this.setInitiallyProvidedValue(params);
this.finalizeConstruction();
}
setInitiallyProvidedValue(params: Child_Params) {
}
updateStateVars(params: Child_Params) {
this.__message2.reset(params.message2);
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
this.__message1.purgeDependencyOnElmtId(rmElmtId);
this.__message2.purgeDependencyOnElmtId(rmElmtId);
}
aboutToBeDeleted() {
this.__message1.aboutToBeDeleted();
this.__message2.aboutToBeDeleted();
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
private __message1: SynchedPropertySimpleTwoWayPU<string>;
get message1() {
return this.__message1.get();
}
set message1(newValue: string) {
this.__message1.set(newValue);
}
private __message2: SynchedPropertySimpleOneWayPU<string>;
get message2() {
return this.__message2.get();
}
set message2(newValue: string) {
this.__message2.set(newValue);
}
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(this.message1);
}, Text);
Text.pop();
Column.pop();
}
rerender() {
this.updateDirtyElements();
}
}
class Child2 extends ViewPU {
constructor(parent, params, __localStorage, elmtId = -1, paramsLambda = undefined, extraInfo) {
super(parent, __localStorage, elmtId, extraInfo);
if (typeof paramsLambda === "function") {
this.paramsGenerator_ = paramsLambda;
}
this.message = 'Hello';
this.setInitiallyProvidedValue(params);
this.finalizeConstruction();
}
setInitiallyProvidedValue(params: Child2_Params) {
if (params.message !== undefined) {
this.message = params.message;
}
}
updateStateVars(params: Child2_Params) {
}
purgeVariableDependenciesOnElmtId(rmElmtId) {
}
aboutToBeDeleted() {
SubscriberManager.Get().delete(this.id__());
this.aboutToBeDeletedInternal();
}
private message: string;
initialRender() {
this.observeComponentCreation2((elmtId, isInitialRender) => {
Column.create();
}, Column);
this.observeComponentCreation2((elmtId, isInitialRender) => {
Text.create(this.message);
}, Text);
Text.pop();
Column.pop()