LiteOS系统JS应用数据变化触发页面刷新流程
1. JS应用代码
- hml
<div class="container" onclick="updateHeight" on:swipe="QuitApp">
<div class="updateDiv" style="height: {{divHeight}}px;"></div>
</div>
- js
export default {
data: {
heightIndex: 0,
heightArr: [50, 100, 150],
divHeight: 50,
},
updateHeight(){
if(this.heightIndex == 2) {
this.heightIndex = 0;
} else {
this.heightIndex++;
}
this.divHeight = this.heightArr[this.heightIndex];
}
}
- css
.container {
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
}
.updateDiv {
width: 6px;
height: 50px;
background-color: #5f7cb8;
border-radius: 2px;
}
2. ace_lite监听数据变化入口 WatcherCallbackFunc
在WatcherCallbackFunc中主要是获取修改的属性和属性值将其传递给组件的UpdateView方法,UpdateView会更新并保存数据,处理成功后触发组件送显。
foundation/arkui/ace_engine_lite/frameworks/src/core/base/js_fwk_common.cpp
jerry_value_t WatcherCallbackFunc(const jerry_value_t func, const jerry_value_t context,
const jerry_value_t *args, const jerry_length_t argsLength)
{
...
bool updateResult = component->UpdateView(attrKeyId, value); // 更新视图及属性数据
if (updateResult) {
component->Invalidate(); // 触发组件送显
}
...
}
3. ui_lite组件属性更新
送显需获取当前组件并记录尺寸和位置等信息,最终将需要更新的区域信息保存到rootView的invalidateRects_中。
foundation/arkui/ui_lite/frameworks/components/ui_view.cpp
void UIView::Invalidate()
{
print_ms("0xc00 updateDiv UIView::Invalidate\n");
UIView* view = this;
while (view != nullptr) {
if (view->transMap_ != nullptr && !view->GetTransformMap().IsInvalid() && view != this) {
InvalidateRect(view->GetRect(), view);
return;
}
view = view->parent_;
}
InvalidateRect(GetRect());
}
# GetRect() 获取需更新区域的尺寸位置等信息
void UIView::InvalidateRect(const Rect& invalidatedArea, UIView* view)
{
rootView->AddInvalidateRectWithLock(trunc, view); // 将要更新的视图信息保存到rootView的invalidateRects_中
}
4. RootView中处理渲染数据及触发送显
rootView中会周期的调用执行RootView::Render(),当前的周期是16ms执行一次,在Render()中会判断 invalidateRects_ 是否为空,当 invalidateRects_ 不为空时,会触发RenderManager::RenderRect(),并最终执行Flush将视图送显。
foundation/arkui/ui_lite/frameworks/components/root_view.cpp
void RootView::Render()
{
...
if (!invalidateMap_.empty()) {
...
RenderManager::RenderRect(flushRect, this); // 处理渲染所需的数据
...
BaseGfxEngine::GetInstance()->Flush(flushRect); // 触发送显到屏幕
...
}
}
RenderManager::RenderRect() 中主要通过调用rootView->DrawTop(topView, mask);将视图更新到最上层,DrawTop则会触发组件本身的OnDraw方法进行绘制数据处理。
void RenderManager::RenderRect(const Rect& rect, RootView* rootView)
{
...
rootView->DrawTop(topView, mask); // 将视图更新到最上层
...
}
void RootView::DrawTop(UIView* view, const Rect& rect)
{
...
curView->OnDraw(*dc_.bufferInfo, curViewRect); // 触发组件本身的绘制逻辑
...
}
div组件最终对应native实现为UIView,在UIView::OnDraw方法中,BaseGfxEngine::GetInstance()->DrawRect则是通过CPU更新需要送显的buffer数据。
foundation/arkui/ui_lite/frameworks/components/ui_view.cpp
void UIView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
{
uint8_t opa = GetMixOpaScale();
BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetOrigRect(), invalidatedArea, *style_, opa); // 更新需要送显的buffer
}
以上执行完成后,执行BaseGfxEngine::GetInstance()->Flush送显到屏幕。
更多推荐

所有评论(0)