什么是适配层?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是适配层?相关的知识,希望对你有一定的参考价值。

所谓的适配层就是用户与网络间的底层交互层,由该层提供端用户与网络的通讯协议,封装并隐藏借口细节。 参考技术A ATM 适配层(AAL)主要负责 ATM 层与高层之间的信元转发过程。从上层收到信息后,AAL 将数据分割成 ATM 信元;从 ATM 层收到信息后,AAL 必须重新组合数据形成一个上层能够辨识的格式。上述操作称之为分段与重组(SAR),它是 AAL 的主要任务。此外不同的 AAL 支持不同的流量或服务类型。 参考技术B ATM适配层
AAL(ATM适配层):标准协议的一个集合,用于适配用户业务。AAL分为会聚子层(CS)和拆装子层(SCR)。AAL有4种协议类型:AAL1、AAL2、AAL3/AAL4和AAL5分别支持各种AAL业务类型。

参考资料:百度百科

OpenHarmony-UI框架适配层浅析

作者:刘永保

前言

方舟开发框架(简称:ArkUI),是一套UI开发框架,提供开发者进行应用UI开发时所必须的能力。提供跨平台能力,集成了类Web开发范式与声明式开发范式两种开发范式。框架分为应用层、框架层、渲染引擎、平台适配和桥接层。本文主要对适配层的部分核心类进行简单介绍,通过这些核心类的关系图和流程交互说明来一窥适配层的部分面貌。

核心类简介

类关系图

  • AceEngine: 全局唯一,提供实例的开门狗注册、垃圾回收能力,同时也作为AceContainer的容器。
  • AceContainer:顾名思义,是一个容器类,由前端、任务执行器、资源管理器、渲染管线、视图等聚合而成,提供了生命周期对接、功能调度接口和UI渲染的各项能力,是平台适配中非常重要的模块。
  • AceAbility: 对应的是FA模型中的PageAbility,是用户具体可见并可以交互的Ability实例。
  • Frontend: 前端框架的抽象,由DeclarativeFrontend、JsFrontend和CardFrontend继承来实现声明式、类WEB及Card方式的实现。
  • PlatformEventCallback:平台事件回调的抽象,不同ability实现各自的回调接口。目前仅支持OnFinish和OnStatusBarBgColorChanged两个事件的回调。
  • AssetManager: 资源管理器的抽象,由FlutterAssetManager实现,最终由FileAssetProvider提供资源文件加载。
  • AceView: 渲染生成视图节点。
  • TaskExecutor: 任务管理器。
  • PipelineContext: 渲染管线。
  • PlatformResRegister: 平台资源的注册和管理,通过接口回调实现平台层的渲染。

协作说明

这里我们以一个典型的APP窗口尺寸发生变化的实现流程来帮助大家理解ACE框架类之间是如何交互的,参见时序图:

步骤说明:

  1. WindowImpl窗口对象感知窗口发生变化,调用监听者的OnSizeChange方法;
  2. 根据ability ID获取对应的AceContainer;
  3. 从AceContainer中获取TaskExecutor任务管理器;
  4. 通过任务管理器创建任务;
  5. 从AceContainer中获取当前View;
  6. 调用FlutterAceView::SurfaceChanged处理界面的变化;
  7. FlutterAceView回调AceContainer注册的viewChangeCallback方法;
  8. viewChangeCallback从PipelineContext渲染管线对象中获取TaskExecutor任务管理器;
  9. 通过任务管理器创建任务;
  10. 任务方法调用渲染管线PipelineContext::OnSurfaceChanged方法处理;
  11. 渲染管线最终调用前端框架OnSurfaceChanged处理界面发生的变化。

关键代码实现:

AceAbility继承自OHOS::Rosen::IWindowChangeListener,作为监听者在OnStart启动的时候向windows对象进行了注册

void AceAbility::OnStart(const Want& want) 
    ...
    // register surface change callback
    OHOS::sptr<OHOS::Rosen::IWindowChangeListener> thisAbility(this);
    window->RegisterWindowChangeListener(thisAbility);
    ...

当界面发生变化,WindowImpl::UpdateRect调用监听者的OnSizeChange处理

void WindowImpl::UpdateRect(const struct Rect& rect, WindowSizeChangeReason reason)

    ...
    for (auto& listener : windowChangeListeners_) 
        if (listener != nullptr) 
            listener->OnSizeChange(rect, reason);
    
    ...

AceAbility::OnSizeChange()

void AceAbility::OnSizeChange(OHOS::Rosen::Rect rect, OHOS::Rosen::WindowSizeChangeReason reason)

    auto container = Platform::AceContainer::GetContainer(abilityId_);
    ...
    auto taskExecutor = container->GetTaskExecutor();
    ...
    taskExecutor->PostTask([rect, abilityId = abilityId_, density = density_, reason]() 
        ...
        auto flutterAceView = static_cast<Platform::FlutterAceView*>(container->GetView());
        ...
        Platform::FlutterAceView::SurfaceChanged(
            flutterAceView, width, height, 0, static_cast<WindowSizeChangeReason>(reason));
    , TaskExecutor::TaskType::PLATFORM);

Platform::FlutterAceView::SurfaceChanged()

void FlutterAceView::SurfaceChanged(
    FlutterAceView* view, int32_t width, int32_t height, int32_t orientation, WindowSizeChangeReason type)

    ...
    view->NotifySurfaceChanged(width, height, type);
    auto platformView = view->GetShellHolder()->GetPlatformView();
    if (platformView) 
        platformView->NotifyChanged(SkISize::Make(width, height));
    
    ...

viewChangeCallback()回调函数

auto&& viewChangeCallback = [context = pipelineContext_, id = instanceId_](
                                int32_t width, int32_t height, WindowSizeChangeReason type) 
    ContainerScope scope(id);
    ACE_SCOPED_TRACE("ViewChangeCallback(%d, %d)", width, height);
    context->GetTaskExecutor()->PostTask(
        [context, width, height, type]()  context->OnSurfaceChanged(width, height, type); ,
        TaskExecutor::TaskType::UI);
;
aceView_->RegisterViewChangeCallback(viewChangeCallback);

PipelineContext::OnSurfaceChanged()

void PipelineContext::OnSurfaceChanged(int32_t width, int32_t height, WindowSizeChangeReason type)

    ...
    auto frontend = weakFrontend_.Upgrade();
    if (frontend) 
        frontend->OnSurfaceChanged(width, height);
    
    ...

延伸

OpenHarmony用户程序的开发本质上就是开发Ability。OpenHarmony系统是通过对Ability调度,结合系统提供的一致性调度契约对Ability进行生命周期管理,从而实现对用户程序的调度。
Ability框架在API 8及更早版本使用FA模型。FA模型中Ability分为PageAbility、ServiceAbility、DataAbility、FormAbility几种类型。其中:

  • PageAbility是具备ArkUI实现的Ability,是用户具体可见并可以交互的Ability实例。
  • ServiceAbility也是Ability一种,但是没有UI,提供其他Ability调用自定义的服务,在后台运行。
  • DataAbility也是没有UI的Ability,提供其他Ability进行数据的增删查服务,在后台运行。
  • FormAbility是卡片Ability,是一种界面展示形式。

AceAbility对应的是FA模型中的PageAbility,和AceContainer容器类搭配管理。其它几种ability在ACE框架中分别对应AceDataAbility、AceFormAbility和AceServiceAbility,使用PaContainer容器类进行管理,关系如下图:

小结

  1. AceAbility是带UI界面的Ability,非UI界面的ability是AceDataAbility、AceFormAbility和AceServiceAbility。
  2. AceContainer是一个容器,聚合了前端、渲染管线和任务执行器等核心功能,相当于一个大总管,ability的关键流程都要经过它调度。
  3. 通过Frontend、PlatformEventCallback、AssetManager和AceView等抽象类,提供了对平台的抽象,通过扩展实现,满足不同平台的适配。

参考链接

方舟开发框架概述:
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ui/arkui-overview.md

Ability框架概述:
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ability/ability-brief.md

FA模型综述:
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/ability/fa-brief.md

OpenHarmony 源码解析之ACE:
https://ost.51cto.com/posts/7908

更多原创内容请关注:深开鸿技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

想了解更多关于鸿蒙的内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://ost.51cto.com/#bkwz

::: hljs-center

:::

以上是关于什么是适配层?的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 -- 适配器模式

ABAP设计模式——适配器

OpenHarmony-UI框架适配层浅析

DAP调试适配协议

PowerBuilder编程新思维3:适配(三层架构与GraphQL)

Android Multimedia框架总结(十三)CodeC部分之OpenMAX框架初识及接口与适配层实现