快速打造一个套壳APP

作为一个前端coder,很少会涉及到需要自己动手打包一个APP的情况,更多的时候,我们都是在现有APP的基础上,以混合开发的模式,将H5页面内嵌到原生APP的webview中。不过,笔者所在的业务线,恰恰接到了一个需要打包一个套壳APP的需求。

需求背景

我司门店的大屏内置Android系统,希望在大屏上可以安装一个应用程序,将已有的业务功能页面内嵌进去。

技术选型

基于以上需求,技术方案选择采用 APP套壳+内嵌H5页面 的模式,这样,只需要开发个适用于大屏的APP安装包即可。方案确定以后,接下来要做的就是寻找适合的框架来开发App安装包了。

在对比了业界主流的跨端框架后,对其特点和差异性,简单做了对比和分析:

框架 Android客户端 打包方式 系统级API
Electron 不支持 本地 具备
Cordova 支持 本地打包 具备
Ionic 支持 本地打包 具备
Weex 支持 本地打包 具备
Hippy 支持 本地打包 具备
Flutter 支持 本地打包 具备
RN 支持 本地打包 具备
uniapp 支持 本地打包、云打包 具备
PWA 类原生 不需要打包 不具备

从上述调研可以看出,大多数的跨端框架都只支持本地打包。本地打包有以下几个弊端:

  • 本地环境搭建麻烦,一般步骤如下:

    • 安装Android Studio

    • 安装Android SDK并配置环境变量

    • 设置Android模拟器

    • 调试Android设备

  • 多人维护时,每人都需要搭建本地环境,成本较高

在尝试搭建本地环境时,耗时一天,期间遇到了各种各样的环境问题,苦不堪言,最终只得放弃。而云打包就省去了本地打包的诸多麻烦,简单来说,云打包就是开发者不需要在本地搭建环境,通过共用云端搭建的环境来打包构建安装包。如此一来,开发者只负责写好代码即可,打包的事交给云服务,岂不完美?

综上,框架自然选择了拥有云打包能力的 uniapp 。它可以让我们以很小的代价完成App打包的工作,达到快速开发的目的。至于 PWA ,由于它缺少系统级API能力,也自然不能入选了。

项目实践

安装HBuilderX编辑器

uniapp 的云打包功能,是集成在HBuilderX编辑器中的,因此我们需要先安装HBuilderX编辑器。

App项目搭建

新建APP项目

首先,我们先通过HBuilderX新建个项目。由于我们只需要一个APP的壳,所以选择默认模板即可。

使用Vue脚手架创建的项目也可以,但是需要手动创建 manifest.json 和 pages.json 文件,HBuilderX新建项目时,会自动创建所需的配置文件。因此,建议直接在HBuilderX上创建项目。

新建的项目目录结构如下:

项目搭建好后,开始改造工作。

原生页面改造

就需求而言,一共需要两个原生页面: 首页 和 webview 。

首页 只承担开屏海报页功能。 webview 用来承载 H5 页面。

首页:index.vue

因此,我们一共需要创建两个页面。首先,我们来改造首页 index.vue :

首页只有一个交互,就是跳转到webview页。

webview页面:webview.vue

下面我们来新建个webview页面 webview.vue :

将 H5 页面链接配置到 webview 组件的 src 属性上即可。

原生页面路由配置

页面的改造已经完成,接下来我们改造路由配置 pages.json :

这里需要说明下:起初,webview页使用的不是 custom 模式,而选择使用默认导航栏。但是默认导航栏有个问题,它的高度是固定的 44px ,无法实现响应式,大屏设备的尺寸很大,导致在大屏上导航栏特别小,尤其返回按钮,点击时很难命中。期间,有尝试使用 uniapp 提供的自定义导航栏,奈何它在webview页面不会生效。最终,我们选择了 custom 模式,在 H5 页面上实现导航栏效果。

另外,除了原生导航栏问题,对于客户端APP来说,还有个很重要的体验问题,就是界面顶部的状态栏。如何隐藏系统的状态栏呢? uniapp 官方也给出了方案。由于我们是要全局隐藏,所以在 App.vue 的 onLaunch 钩子函数中,添加 plus.navigator.setFullscreen(true) 即可,如下:

<script>
 export default {
  onLaunch: function() {
   plus.navigator.setFullscreen(true)
  }
 }
</script>

路由配置完成后,接下来需要进行应用的相关配置 manifest.json :

应用配置

基础配置

首先来看 基础配置 :

这里的 AppID 是在 uniapp 的 开发者中心 创建应用时 DCloud 云端分配的,如果是多人合作的项目,记得进入应用,添加项目成员。

App图标配置

接下来进入到 App图标配置 :

项目的图标都存放在 static 目录下,否则会找不到文件。

以上,我们的项目改造和配置工作就完成了,接下来开始我们的打包之旅。

云打包

在HBuilderX编辑器中,点击 工具栏 – 发行 – 原生App-云打包 :

弹出如下窗口,选择 Android(apk包) ,定义自己的 Android包名 ,选择 使用公共测试证书 ,接着选择 打正式包 ,最后点击 安心打包 即可,如下图:

打包之后,会看到控制台的输出如下:

如果打包完成,会在本地项目的 /unpackage/release/apk/ 文件夹下,生成本地的安装包。老版的HBuilderX会将安装包放到云上,打包完成后给出下载地址,而且这个下载地址是有下载次数限制的。v3版本更新后,直接打包在本地,免去了下载次数限制的烦恼。

这里需要注意下, uniapp 的云打包虽然极大方便了我们生成安装包,但是因为是公用资源,每个账号每天的打包次数是有上限的, uniapp 官方并不建议频繁打包调试,建议大家在使用时,本地充分测试后,再进行打包。

若同一时段内,使用云打包的人较多,控制台会显示 队列中 ,耐心等待即可。

原有H5项目改造

内嵌在webview中的H5页面,少不了要和首页交互,比如返回首页功能,因此还需要对H5页面进行改造。

由于H5页面是多端复用,需要对大屏进行单独处理,所以先要根据 userAgent 判断终端。 uniapp 官方是支持自定义 userAgent 内容并可选择追加模式,不过实践得知,并不生效。

配置路径在 manifest.json 的 源码视图 中配置。

既然不能实现自定义,那就只能获取默认的 userAgent 来作为判断终端的依据了。好在目前只有这一个APP,倒也可用。

判断终端的方法如下:

window.navigator.userAgent.indexOf('uni-app Html5Plus') > -1

若要与原生页面交互,还需引入 uniapp 的SDK uni.webview.1.5.2.js :

<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>

如此,便可调用 uniapp 的方法了。比如:点击返回首页按钮,回到 index 海报页,可使用:

uni.redirectTo({
  url: '/pages/index/index'
})

如此,项目打造的详细步骤已经全部完成,赶紧找个安卓手机,安装试试吧~

遇到的问题

整个项目打造的过程中,坑点不多, 导航栏 、 状态栏 和 userAgent 的问题,前面已经介绍过,这里不再赘述。接下来主要说下打包遇到的问题:

  1. 运行环境版本和编译器版本不一致

这个问题是由于uni-app添加了运行环境版本和编译环境版本的校验机制导致的,官方文档:uni-app运行环境版本和编译器版本不一致的问题有很详细的说明,具体请参照文档。

  1. 若代码中使用了scss/sass语言,而HBuilderX没有安装相应插件,预编译阶段会提示:

点击控制台提示链接,跳转到指定页面,按提示安装插件后,再重新编译打包即可。

  1. 权限拦截

打包过程中,如果遇到上述提示,请检查 manifest.json 中 App权限配置 中是否勾选了某权限,但是系统又不允许,若是且此权限不是必须,可取消勾选,再重新打包。

总结

有同学可能会问,本着专业的人做专业的事的原则,原生App的工作不是应该交给客户端同学来做吗?在这里说明下,之所以这个工作前端同学来做,原因有三:

  1. 当时这个安装包要的很急,门店开业在即,客户端同学资源有限,排期比较靠后

  2. 我司的客户端同学,属于业务支撑性质的部门,几乎所有的业务线需求都是H5实现的,所以注定了客户端同学不可能持续跟踪迭代版本更新,所以这个安装包如果能由前端同学来负责开发是最好的。

  3. 有最合适的框架做技术支撑,可能让我们很轻松地完成,理所当然承担起了这个工作。

基于以上原因,并不是笔者心血来潮盲目就要做客户端,是做了充分考虑的,希望大家在对待需要开拓的领域或新的框架时,可以保持冷静,仔细端详。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注