当前位置:首页 > 谈天说地

​​​​​​​Android H5通用容器架构设计详解

34资源网2022-09-06405

背景

大家如果经历过hybrid项目的开发,即项目中涉及到h5与native之间的交互,那么很有可能会遇到各种各样的h5容器。为什么会有那么多各种各样的容器呢...这也是轮子多的通病了,轮子多到业务方不知道选哪个。当然,也有可能大家压根就不会使用到h5容器,直接用系统webview就完事儿了,比如我的前东家就是这样做的。那这篇文章的主题就是与前者相关的:当项目中拥有很多个h5容器时,怎样封装才能让业务侧用得爽呢? 

下面按惯例,抛出这篇文章要解决的三个问题:

  • 如何优雅地提供接口调用?
  • 怎样封装多个不同类型的h5容器?
  • 这样的架构能带来什么样的好处?

术语对齐

术语 描述
h5框架容器 特指目前项目中正在使用的二方/三方h5容器。
h5通用容器 特指将项目中所有的框架容器抽象到一个容器中,让业务侧不需要感知到具体的框架细节。
a页面 url query参数中带a=true的页面,项目中用a容器承载。
b页面 url query参数中带b=true的页面,项目中用b容器承载。

探索

如何优雅地提供接口调用?

业务侧调用的接口其实很有限,可以说90%的业务都只是打开一个网页而已。

我们根据业务需要新建一个接口类:

/**
 * webpage服务接口类
 */
public interface iwebpageservice {
    /**
     * 打开url
     * @param url
     */
    void openurl(string url);

    /**
     * 创建fragment内置到某页面中使用
     * @return
     */
    fragment buildfragment(string url, context context);

    /**
     * 获取当前url
     * @return
     */
    string getcurrenturl();

    /**
     * 给h5发通知
     * @param eventdata
     * @param eventname
     */
    void postnotificationtojs(string eventname, string eventdata);
}

以上列举了4个非常常见的接口。如果有需要,还可以扩展其它的,比如设置容器生命周期相关的监听、设置h5发通知来时的监听等等。拿openurl的实现举例,实现类通过url中的参数判断需要打开a容器还是b容器

@override
public void openurl(string url) {
     // 若url中含有a参数,则用a容器打开
     // if (urlparamhasa) {
        // startacontainer();
     // } else {
        // 否则用b容器打开
        // startbcontainer();
     //}
}

这就从接口层这一层面屏蔽了内部框架容器。其它接口也是类似,原则就是不让业务侧感知到具体的实现细节,而不是跳个页面还需要知道这个url是要用a容器打开还是b容器打开。在应用启动时,可以将实现类注入到公共依赖中去,也可以通过arouter等框架实现依赖注入,方便业务侧的调用。

怎样封装多个不同类型的h5容器容器?

整体架构

先上一张图:

接口层上面已经讲过了,这里我们直接看容器层。

通用容器

第一层就是我们抽出来的通用容器,webpageactivity与webpagefragement。项目中,不管是哪个h5框架容器,势必都是用activity或者fragment来承载的,所以我们相应的也需要有这两者作为父类去进行封装。而通用容器中,最重要的职责就是去执行通用逻辑,即每个框架容器都需要执行的逻辑。

通用职责可以有以下几点:

  • 设置页面属性,包括window flag、activity的主题等。
  • 解析url,将url中的关键参数记录下来,从而决定以哪种策略渲染ui。比如可以通过disablenav参数决定是否显示导航栏,通过statusbarstyle参数决定状态栏的风格等。
  • 控制通用ui的渲染,包括何时改变titlebar、何时加载/隐藏loading,何时渲染异常态ui等。
  • 决定框架容器加载时的逻辑顺序,如setcontentview()->loadurl()。
  • 接收生命周期事件与系统回调事件,并且分发回调。生命周期就不用说了,系统回调这里特指onactivityresultonrequestpermissionresult这类事件,然后将结果分发给各listener。

webpageactivity#oncreate举例:

@override
protected void oncreate(bundle savedinstancestate) {
    // setwindowflags(); 设置window属性
    // settheme(); 设置主题
    // settransition(); 设置转场动画
    
    super.oncreate(savedinstancestate);

    // parseurl(); 解析url
    // initcommonui(); 渲染通用ui 比如titlebar、底部导航栏等
    
    setcontentview();
    loadurl();
}

protected abstract void setcontentview();

protected abstract void loadurl();

我们可以将设置window属性、设置主题这些通用行为放在通用容器中执行,而setcontentviewloadurl交由框架容器去执行。setcontentview是因为不同的容器,layout xml可能是不一样的。loadurl是因为每个容器用webview去加载url的方式也可能不同,无法统一。类似的行为,若执行时机可统一,则由通用容器统一执行时机,比如setcontentviewloadurl。若时机也没法确定,甚至逻辑只会存在于某个框架容器中,那么就要写到子类中去了。

框架容器

图中第二层的容器a、容器b、容器c指的就是框架容器。有了通用容器承载共同的逻辑后,框架容器需要做的事情就比较少了。只需要加载各自的布局,初始化webview,然后将url加载到webview中就可以了(除非有某个框架容器需要特殊适配,那就得写些额外的代码)。具体的实现需要根据项目中框架容器的使用方式来确定。

基础组件

第三层表示基础组件。这里只列一些常见的基础组件。

  • components:各类ui组件,比如titlebar与异常态控件。
  • js bridge:js bridge可以单独放到一个类中做收口,然后分发给各个listener。listenr通过接口层进行注入。
  • webviewclient:webviewclient在日常开发中算是维护的非常频繁的一个类,职责主要是在shouldoverrideurlloading重定向时对url进行拦截,以及根据相应的生命周期回调(onpagestarted、onpagefinished、onreceviederror等)进行loading或异常态ui的渲染时。若每个框架容器可以设置同一个webviewclient,那就非常方便了,只要改一处地方,所有容器就都生效了。
  • interceptors:即用于webview重定向时的拦截器。像我的项目中会有很多拦截相关的逻辑,比如将a页面拦截跳转到原生页面,就需要在重定向时进行拦截。但逻辑堆叠太多会提高维护的成本,因此建议用责任链模式(没用过的同学可以百度一下,很简单滴~)去处理拦截的这块逻辑。
  • managers、listeners:容器中总是需要很多辅助类去来帮助我们去管理一些东西,比如webview的管理,url的管理。这里就不延伸了,根据实际需要去加。listener也一样,关于容器生命周期的listener,与js bridge交互相关的listener,都可以通过接口层去实现注入与销毁。

当然,除此之外,根据每个项目的完整度与负责度,还会衍生出很多基础组件。比如h5的监控体系,h5的预加载体系,以及webview预创建相关的缓存体系等。他们作为框架容器共同的底座承担相应的职责。

这样的架构能带来什么样的好处?

  • 对业务侧而言,接口统一收口到iwebpageservice中去,调用方式更加简单明了,不需要再关注容器的具体类型。
  • 对容器侧而言,代码逻辑性清晰的同时,有效降低了日后的维护成本与开发成本。loading、异常态不需要再在各类容器中重复写n遍,各种url params都统一收口到通用容器中去,重定向拦截逻辑也不再需要重复写n遍...总而言之,通用逻辑统一给通用容器与基础组件去承担,框架容器的代码,都是各框架容器所“独有”的。

到此这篇关于android h5通用容器架构设计详解的文章就介绍到这了,更多相关android h5容器架构内容请搜索萬仟网以前的文章或继续浏览下面的相关文章希望大家以后多多支持萬仟网!

看完文章,还可以扫描下面的二维码下载快手极速版领4元红包

快手极速版二维码

快手极速版新人见面礼

除了扫码领红包之外,大家还可以在快手极速版做签到,看视频,做任务,参与抽奖,邀请好友赚钱)。

邀请两个好友奖最高196元,如下图所示:

快手极速版邀请好友奖励

扫描二维码推送至手机访问。

版权声明:本文由34楼发布,如需转载请注明出处。

本文链接:https://www.34l.com/post/21725.html

分享给朋友:

相关文章

30句用喜从天降造句的语句

30句用喜从天降造句的语句

1、让他去泰山旅游,那真是喜从天降。…

天上的孩子电影好看吗?看豆瓣网友如何评价的吧

天上的孩子电影好看吗?看豆瓣网友如何评价的吧

由胡玫监制许磊导演编剧的电影《天上的孩子》。电影主要讲述了来自贵州的夫妻老何、玲霞5岁的独子查出绝症,不久于人世。为了让儿子的名字刻在纪念碑上,夫妻俩决定捐献儿子的器官却困难重重。…

为了让米粉买到好看的手机壳,雷军投了一家“潮玩工厂”

为了让米粉买到好看的手机壳,雷军投了一家“潮玩工厂”

小米团队花了几个月时间,想要找到一个能DIY打印手机壳的设备却没有找到。直到2020年底,他们在西单大悦城看到玩壳工厂。 “用户需求一直存在,早前也有不少团队尝试开发这样的设备,但都失败了。”玩壳工厂创始人CEO韩冰告诉创业邦。 如今,玩壳…

B站、爱奇艺:这对难兄难弟

11月17日,哔哩哔哩(下称“B站”)与爱奇艺发布截至2021年9月30日的第三季度财报。B站Q3营收52.066亿元,同比增长61%,净亏损26.863亿元;爱奇艺Q3营收75.891亿元,同比增长6%,净亏损16.984亿元。 两家先后…

ab压力测试命令(在线ddos免费测压平台)

ab压力测试命令(在线ddos免费测压平台)

ab 是apache对 http服务器进行压力测试的工具,它可以测试出服务器每秒可以处理多少请求。本文记录mac版本安装 ab 的步骤以及遇到的坑。 下载 进入 apache ab官网 下载页面。 安装 brew 安装 因为笔者的操作系统…

微信直接打开淘宝抖音,但李佳琦罗永浩带货,买不了

微信直接打开淘宝抖音,但李佳琦罗永浩带货,买不了

图源:摄图网 编者按:本文来自微信公众号IT时报(ID:vittimes),作者:江丽雯,编辑:郝俊慧 挨踢妹,排版:季嘉颖,创业邦经授权转载 11月29日,微信放开了对外链的限制。 当日发布的《关于〈微信外部链接内容管理规范〉的更新声明》…