Hybrid App(原生+H5)开发

news2024/11/29 6:24:36

介绍

市面上主流的hybrid app框架主要有

  • React Native:由FaceBook开发,使用JavaScript和React来构建原生应用程序
  • Flutter:由Google开发,使用Dart语言。Flutter使用自己的渲染引擎
  • Ionic:基于 Web 技术(HTML、CSS 和 JavaScript),使用 Angular 框架。Ionic 提供了一组 UI 组件和工具,使开发人员能够构建跨平台移动应用程序。

还有hybrid app框架,但是我本人没有进行过多的涉及,这里就不展开了,想要进一步了解的友友们可以自行查阅资料哈。我在这主要是想讲讲使用hybrid app开发时的一些使用方案,并且结合自己现在做的,总结一下自己的心得。

要解决的问题

  • web调用原生(实质是JavaScript调用Java)
  • 原生调用web(实质是Java调用Java)
  • 数据通道的搭建---性能及易用性

原生+webVview方案

这是最常用的Hybrid方案之一。应用的主要框架由原生代码构建,同时在应用的某些部分内嵌入WebView组件,用于显示Web页面加载Web应用。Web页面通过WebView运行,并可以与原生代码进行通信。通俗点来说,就是网页的模式,通常由“HTML5云网站+APP应用客户端”两部分构成。混合开发是一种取长补短的开发模式,原生代码部分利用WebView插件或者其他框架为H5提供容器。

优点:

  1. 开发效率高,节约时间。同一套代码在Android和IOS上基本都可以使用
  2. 更新迭代以及部署比较方便,每次升级版本只需要在服务器端升级即可,不需要再上次App Store进行审核
  3. 代码维护方便,版本更新快,节约产品成本
  4. 基于web,但是同时也可用拥有原生支持的业务
  5. 可离线运行

缺点:

  1. 功能/界面无法自定:所有内容都是固定的,不能换界面或者增加功能
  2. 加载缓慢/网络要求高:混合APP数据需要全部从服务器获取,每个页面都需要重新加载,因此打开速度慢,网络占用高,缓冲时间长,容易让用户反感

但是webview也是有一定的缺点的,即web应用的体验无法达到原生应用的体验。但是开发效率高,被很多app所用。比如京东、淘宝、今日头条等APP都是利用混合开发模式而成的。这也是目前笔者开发团队中开发APP时最经常使用到的方案。

H5和原生如何交互的呢?

        H5与原生APP的交互指的是在原生APP中嵌入H5页面,是的用户可以在原生APP中直接访问H5页面并进行交互操作。H5与原生APP交互原理是通过webview实现的。那么webview又是什么呢?

webview

webview是Android和IOS系统中提供的一个组件,使得可以在原生APP中嵌入H5页面。webview可以加载HTML、CSS、JavaScript等web技术,同时也可以调用原生APP提供的API,实现与原生APP的交互

H5与原生交互方式

        在H5页面中,可以通过JavaScript调用原生提供的API,实现与原生的交互。原生APP需要提供一个JavaScriptBridge类,用来接收H5页面发来的请求,并执行相应的操作。

        我这里主要想讲一下如何应用第三方框架实现H5与原生之间的交互。目前比较流行的支持H5与原生App之间交互的框架有:WebViewJavaScriptBridge、JSBridge、HybridBridge等。这些框架都提供了API接口,方便H5页面与原生APP的交互,同时也提供了一些辅助功能,如:H5页面的路由跳转、原生APP的Toase提示、H5页面的Loading动画等。

        笔者主要是从事前端开发的,那么也就是在进行Hybrid APP开发时负责的是H5页面的开发,然后我们团队用到的实现与原生APP之间交互的第三方框架主要是dsBridge,所以接下来我也主要围绕dsBridge展开,讲述H5与原生交互的一些主流程以及实际应用。

DSBridge

介绍

  • 国内推出的JavaScript bridge跨平台混合开发框架
  • 官方提供了Android/ios版本,真正实现跨平台
  • DSBridge支持同步及异步调用(DSbridge是唯一一个支持同步调用的javascript bridge)
  • 无需iFrame,性能好
  • Github地址
    • IOS:GitHub - wendux/DSBridge-IOS: :earth_asia: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native.
    • Android:GitHub - wendux/DSBridge-Android: :earth_americas: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native.

DSBridge的接入方式

原生端

  • 直接源码接入
    • 下载DSBridge源码,作为独立的Module接入工程
  • Gradle依赖
    • 配置Gradle脚本,Sync自动接入

H5端

  • npm进行下载:npm install dsbridge -g
  • cdn方式引入
  • 直接下载源码,放到指定的js文件中进行引入(后文会贴上dsBridge的源码)

H5与原生交互的核心

在web和原生之间进行交互,如传递数据,调用函数,那么其交互的核心就是要解决双方之间的通信问题,且其中分为H5调用原生提供好的接口,和原生调用H5注册好的方法。那么H5和原生之间是如何通信的呢?

H5调用原生

steps:

  1. 原生在webview上注册方法,以提供JavaScript调用
  2. H5初始化DSBridge上下文环境(H5便可以使用DSBridge提供的一些api方法)
  3. H5端使用dsBridge.call()直接调用原生端提供的方法

原生端调用H5端

steps:

  1. 前端注册注册JavaScript方法以供原生端使用
  2. 客户端获取DWebView实例(DWebView:其实dsBridge对webview只做了一层封装,提供了dsBridge特有的JavaScript到Java的能力)
  3. 客户端通过callHandler函数调用H5注册的JavaScript方法,并且传入一个回调函数。 

 同步调用及异步调用

原生端注册同步异步方法的方式

  • 同步调用:public object handler(object arg)
    • 参数arg是给H5回传的数据
  • 异步调用:public void handler(Object arg,CompletionHandler handler)
    • 参数arg是给H5回传的数据
    • handler是回调接口,在前端执行一定操作逻辑之后,通过handler去回调消息

原生提供给H5调用的方法

同步调用

1.原生端注册同步方法

注意点:

  • 原生端注册同步方法,参数msg必填,h5可以不传
  • 注解必须加上,h5端才能调用(dsbridge的一个安全措施)

 2.在指定url的webview页面注入刚才写好的提供给H5调用的方法,这个才能实现真正供H5调用

3.H5端进行调用

  • 初始化DSbridge(引入DSBridge)
  • 使用dsBridge.call('方法名',obj)    // obj是在指定方法中传给原生的参数 

效果(这里实例的是安卓应用):

 

异步调用

 步骤跟同步调用大同小异,这里就不展开。但是需要注意的是,这里呀原生异步注册时和H5调用时区别

H5注册方法供原生调用

同步调用

1.前端注册同步方法

2.原生端调用H5注册的同步方法

逻辑梳理:

1.这里loadUrl指明了webview指定页面,点击指定元素触发onClick方法

2.方法中调用了callHandler方法调用了H5注册的toUpper方法,同时传入'hello'参数。

3.H5拿到参数之后,对其进行操作,这里是大小写转换,

4.H5将转换后的数据return给到原生端,原生端拿到retValue值进行一些其他操作(这里进行Toast)

异步调用

1.前端注册异步方法

2.原生端调用H5注册的异步方法

逻辑梳理:

1.前些步骤与同步调用一样

2.差异在于前端注册异步方法是没有传递其他参数,直接传一个回调函数,前端自行决定执行一些其他操作逻辑

总结:以上便是通过原生端和H5几个简单的例子说明H5是如何通过DSBridge实现与原生端的交互的。接下来我将从H5端实际项目出发,讲讲我在进行hybrid app开发时,是如何使用DSBridge实现与原生端的通信的。

项目中的应用

引入DSBridge

我在项目中使用的是直接下载源码,放在js文件中,然后再项目入口文件中进行初始化(便可以全局引用),当然也可以使用下载依赖的方式,然后再main.js文件中使用node模块进行require导入。

方式1:

安装

npm install dsbridge@3.1.4

引入:在文件夹src\utils\dsbridge.js中引入(这里可以做一层封装)

var dsBridge = require('dsbridge')
export default {
  callmethod (name, data, callback) {
    callback(dsBridge.call(name, data, callback))
  },
  registermethod (tag, callback) {
    dsBridge.register(tag, callback)
  }
}

方式2

安装

下载deBridge.js源码放在src\utils\dsbridge.js文件下

引人:在main.js文件中引入

import dsBridge form '../src/utils/dsbridge'

使用

定制协议

1.【通用】跳转新页面 / gotoPag

方法名:gotoPage

是否同步:同步

功能:原生端提供给 H5,用于页面跳转

参数:{ url: '' }

返回值:无

H5 示例:

let url = "http://192.168.150.148:8000/device/timer" + 
"?deviceId=" + devId;
dsBridge.call("gotoPage", { url: url })

 2.获取账户信息 / getAccountInfo

方法名:getAccountInfo

是否同步:同步

功能:获取家庭名称、设备名称信息

参数:无

返回值:homeName 【家庭名称】, homeTimezone【时区】

H5 示例:

let homeRes = dsBridge.call("getAccountInfo", {}); // 返回
{ homeName: "test", homeTimezone: 0 }

3.局域网下图片相对路径处理 / imgSrcBase64

方法名:imgSrcBase64

功能:H5 传回图片相对路径,原生对缓存图片进行 base64 处理

是否同步:异步

传参: { src:'' }

4.返回:base64 字符串 / imgSrcBase64CallBack

方法名:imgSrcBase64CallBack

是否同步:异步

功能:原生返回缓存图片的 base64 字符串

返回:base64 内容

注:原生端将缓存图片转 png 格式,再进行 base64 处理,返回 base64 字符串,H5 自 行拼接前缀:data:image/png;base64, 

调用原生注册的方法

一般在项目中需要调用到原生端注册的方法的业务方法,我会抽离到一个文件中集中管理。比如我将其放在utils/dsBridgeSend.js文件中

export default {
  /**
   * 定时界面跳转
   * */
  toTimePage(devId) {
    //  测试用
    let url = 'http://192.168.151.30:8001/device/timer' + '?deviceId=' + devId
    dsBridge.call('gotoPage', {
      url: url
    })
   }
  /**
   * 获取设备使能值信息
   * */
  getDevEnable() {
    dsBridge.call('getDevEnable', {})
  },
  /**
   * 导航栏配置公共方法
   * */
  pageBarSetting(devName) {
    let config = {
      hiddenBar: 0,
      title: devName,
      left: [
        {
          type: 2,
          localImageIndex: 7
        }
      ]
      right: [
        {
          type: 2,
          localImageIndex: 9
        }
      ]
     dsBridge.call('configTopBarWithParams', config)
  },
  /**
   * 调用后台接口通用方法-通过原生端
   * */
  requestFunction(ind, params) {
    let requestItem = requestItem.method,
      url: requestItem.url,
      callBackMethodName: requestItem.callBackMethodName,
      errorCallBackName: requestItem.errorCallBackName,
      params: params
    }
    dsBridge.call('requestFunction', query)
  },
}

注册方法以供原生调用

H5这边注册方法以供原生调用,  mounted() {
这个时机一般是发生在页面(或者说webview页面)加载时,所以一般是放在页面挂载的声明周期中【Vue2:mounted(),Vue3:onMounted()】

mounted(){
    let _this = this;
    dsBridge.registerAsyn("async", {
      tag: "async",
      queryDeviceInfoCallBack: function (response) {
        if (_this.$dsBridgeSend.handleError(response)){
          const res = JSON.parse(response).result;
          //  解析状态值
          _this.setStatus(res.status);
        }
      },
      ctrlSucCallBack: function (response) {
        const res = JSON.parse(response)
        // 接收相同的deviceId才进行处理返回值
        if (_this.$common.matchDeviceId(response, _this.commonObj.deviceId)) {
          // 发送指令后 - 获取返回值
          _this.changeIdList.map((i) => {
            i.changeId++;
            _this.updateStatus(res.deviceStates)
        }
      },
      left_0_click: function (responseCallback) {
        dsBridge.call("goBack", 4, function () {}
        responseCallback();
      },
      right_0_click: function (responseCallback) {
        if (Number(_this.isEdit) === 1) {
          _this.deleteContact()
        } else {
          _this.addContact()
        }
        responseCallback();
      },
    });
  },

总结:

混合开发的一个主要流程:

1.根据需求规划,哪些业务是H5负责,哪些是原生端负责

2.定制一份约束双端的协议以用来对应方法的一一对应性(什么方法做什么事,参数、方法名、同步异步)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1172165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索无限可能:APITable免费开源多维表格与可视化数据库远程访问的魅力

APITable免费开源的多维表格与可视化数据库公网远程访问 文章目录 APITable免费开源的多维表格与可视化数据库公网远程访问前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台&#xff0c…

【Java初阶练习题】-- 数组练习题

数组练习题 1. 创建的数组,并且赋初始值2. 改变原有数组元素的值3. 数组所有元素之和4. 奇数位于偶数之前5.两数之和6. 只出现一次的数字7. 多数元素8. 给你一个整数数组 arr,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在&…

Kibana中使用Dev Tools控制台创建索index索引同时添加date类型的时间参数(用于根据时间序列展示数据)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

android studio 字节码查看工具jclasslib bytecode viewer

jclasslib bytecode viewer 是一款非常好用的.class文件查看工具; jclasslib bytecode editor is a tool that visualizes all aspects of compiled Java class files and the contained bytecode. Many aspects of class files can be edited in the UI. In addit…

AD教程(六)现有元件模型的调用

AD教程(六)现有元件模型的调用 导入现有原理图 Altium Schematic Document (.SchDoc) 直接拖入AD即可 直接用现有原理图生成原理图库 点击设计,选择生成原理图库,进入归类设置界面(用原理图直接生成原理图库&#xf…

【漏洞复现】Apache_HTTPD_未知后缀名解析

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 upload-labs/Pass-07 上传1.php文件 <?php eval($_REQUEST[6868]);phpinfo();?>访问/upload/1.php.jaychou 蚁剑连接

(自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载

(自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载 带后台系统PbootCMS内核开发的网站模板&#xff0c;该模板适用于新闻博客网站、自媒体运营网站等企业&#xff0c;当然其他行业也可以做&#xff0c;只需要把文字图片换成其他行业的即可&#…

linux的另一种判断符号【中括号】

由于正在表达式的关系&#xff0c;所以如下 第一、括号内每个组件需要空格分隔 第二、变量最好用双引号 第三、常量最好用单引号或双引号 中括号常用条件判断是 if then fi 为啥发3张图片&#xff0c;因为运行的试试程序报错&#xff0c;说我语法错误“”&#xff0c;可以…

06、三数之和:给你一个整数数组 nums ,请你返回所有和为 0 且不重复的三元组。

文章目录 1、题目描述1.1 移动所有零至数组末尾1.2 示例 2、解题思路2.1 思路讲解2.2 动画演示&#xff08; 待补充&#xff09; 3、答案3.1 Java 代码3.2 运行结果 4、视频讲解&#xff08; 待补充&#xff09; 1、题目描述 1.1 移动所有零至数组末尾 给你一个整数数组 nums…

微服务架构——笔记(2)

微服务架构——笔记&#xff08;2&#xff09; 一、客户客户端模块 文章来源B站视频 尚硅谷SpringCloud框架开发教程(SpringCloudAlibaba微服务分布式架构丨Spring Cloud)教程 本次笔记内容为消费者订单Module模块 1.1 项目名称、目录结构 1.2 Pom.xml <?xml version&q…

box-shadow

0 参数解释 box-shadow:inset offset-x offset-y blur-radius spread-radius color; **inset&#xff1a;**有inset 则为内阴影&#xff0c;没有insert 则为外阴影&#xff0c;默认为外阴影 **offset-x&#xff1a;**横向阴影的大小。正值阴影在右边&#xff1b;负值阴影在左边…

spring入门程序

2023.11.4 今天学习了一下spring的简单使用。 首先需要配置一下spring context和junit的依赖&#xff0c;在pom.xml文件中添加&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><ver…

http中的Content-Type类型

浏览器的Content-Type 最近在做web端下载的时候需要给前端返回一个二进制的流&#xff0c;需要在请求头中设置一个 writer.Header().Set("Content-Type", "application/octet-stream")那么http中的Content-Type有具体有哪些呢&#xff1f;他们具体的使用场…

双十一首战捷报丨Kaadas凯迪仕智能锁品类全网第一 获央视二套采访报道 尽显行业头部品牌风采

2023“双十一”购物狂欢节在如火如荼进行中&#xff0c;智能门锁品类作为智能家居安全体系的重要组成部分&#xff0c;在今年活动中又一次迎来了大卖&#xff0c;智能锁成为了人们购物车里的热门商品。 延续往年势头&#xff0c;Kaadas凯迪仕智能锁今年双11在各大电商平台再次取…

涉及多种位运算操作混合类题目——通过加转三进制(扩大状态,不变枚举量):CF1033F

https://www.luogu.com.cn/problem/CF1033F 我们发现直接用二进制来做很难做&#xff0c;但我们可以观察其给的表 我们发现如果表示成和的形式是容易进行一一对应的 对于询问的时候&#xff0c;我们直接枚举每位有的和是多少&#xff0c;虽然状态是三次的&#xff0c;但是对于…

java毕业设计基于springboot+vue线上教学辅助系统

项目介绍 本论文主要论述了如何使用JAVA语言开发一个线上教学辅助系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述线上教学辅助系统的当前背景以及系统开…

【漏洞复现】Metinfo5.0.4任意文件包含漏洞复现

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1、蚁剑直接连接图片马2、读取敏感目录3、读取php源码4、执行PHP命令5、包含木马写Shell &#xff08;图片马制作新方法&#xff09; 以 metinfo_5.0.4为例 该环境的文件上传…

Building wheel for scipy (setup.py) ...卡着

【Q】:安装torch等的时候遇到问题&#xff1a; 那就安装这些库呗&#xff0c;执行“python -m pip install matplotlib2.0.0 scipy1.0.1 tifffile2019.7.26” 结果出现下列情况&#xff1a;&#xff08;xx的魔力转圈圈&#xff09; 再次执行&#xff1a;python -m pip instal…

[极客大挑战 2019]Knife 1(两种解法)

题目环境&#xff1a; 这道题主要考察中国菜刀和中国蚁剑的使用方法 以及对PHP一句话木马的理解 咱们先了解一下PHP一句话木马&#xff0c;好吗&#xff1f; **eval($_POST["Syc"]);** **eval是PHP代码执行函数&#xff0c;**把字符串按照 PHP 代码来执行。 $_POST P…

项目构建工具maven的基本配置

&#x1f451; 博主简介&#xff1a;知名开发工程师 &#x1f463; 出没地点&#xff1a;北京 &#x1f48a; 2023年目标&#xff1a;成为一个大佬 ——————————————————————————————————————————— 版权声明&#xff1a;本文为原创文…