plus 是什么?—— 超详细解析
下面这份答复将从 技术原理、历史背景、运行机制、核心模块、常见功能、进阶技巧、调试方法、性能与安全、与其他方案的对比、生态与插件开发、常见问题排查 等多方面,极其详细地介绍 plus (即 H5+)的方方面面。希望能够全面、深入地帮助你理解和使用它。
目录
5. plus.io:文件系统
8. plus.uploader / plus.downloader:上传与下载
10. plus.key:物理按键
14. plus.push:推送功能
15. 其他模块(plus.share, plus.pay 等)
2. 与 Weex 的比较
3. 与纯原生开发的比较
1. 插件开发原理
2. 如何创建自定义插件
3. 插件管理与版本更新
一、H5+ 与 plus 的历史背景
- DCloud 公司与 H5+ 规范
- DCloud(数字天堂)推出了 HBuilder、HBuilderX 等前端开发工具。
- H5+ 规范由 DCloud 提出并实现,旨在将移动 App 的 原生功能 通过 JavaScript 暴露给前端开发者,从而让大家能用 HTML5/CSS3/JS 做高性能 App。
- 为什么会出现
plus
- 纯 Web 技术通常无法访问手机操作系统的底层功能(如存储、摄像头、蓝牙等)或访问能力有限。
- DCloud 借鉴了 PhoneGap/Cordova 的思想,但对底层做了更深度的优化与封装,形成了自己的 H5+ 引擎 。
- 在 H5+ 引擎中,JavaScript 运行环境被注入了一个全局对象 plus,该对象中包含了调用原生功能的各种接口,类似于浏览器中 window 对象扩展了一系列原生能力。
- 早期应用
- 早期的 MUI (DCloud 推出的前端 UI 框架)就是基于 H5+ 技术,允许开发者在 WebView 中使用 plus。
- 随后,DCloud 又在 uni-app 中整合了更多的多端能力,同时 App 端依然沿用 plus 提供的原生功能。
- 发展现状
- 目前,plus 已是 DCloud 家族中最核心的模块之一,被广泛使用在 uni-app、原生 5+ App、HBuilderX 的真机运行等场景。
二、plus 的运行机制与核心理念
- 运行原理
- 移动端 App 内嵌一个或多个 WebView 。
- WebView 中运行 HTML/JS/CSS,当 App 启动后,底层会将 plus 对象注入到 WebView 的 JavaScript 环境。
- 当 JavaScript 调用 plus.xxx 的某个方法时,会通过一套原生层桥接(bridge)机制,调用到 iOS/Android 的本地代码。
- 原生层执行完毕后,再将结果通过同样的桥接通道返回给 JavaScript。
- 核心理念:让前端工程师可以不写原生代码,却能用到原生能力
- 开发者只需要掌握 Web 前端技术 + plus API,就能完成原生 App 的大部分功能。
- 这极大地降低了移动 App 开发的门槛,同时享有较高的开发效率。
- 与
uni.系列 API 的关系
- 在 uni-app 中,部分原生能力由 uni.xxx(如 uni.getLocation 等)封装,这些接口底层往往会调用到 plus.xxx(仅在 App 端生效)。
- 如果某些 uni. 接口无法满足需求,或者需要用到更底层、偏原生的能力,则可以直接调 plus.xxx。
- 使用环境判断
- 如果在微信小程序或浏览器内,plus 对象不会存在。
- 在 uni-app 的 App 端或 HBuilderX 真机运行模式下,plus 才会被注入。
- 通常需要写逻辑判断:
```js
if (typeof plus !== 'undefined') {
// 安全使用 plus
} else {
// 不在 App 端,plus 不可用
}
```
三、plus 的主要模块与功能大全
plus 拥有诸多子对象,每个子对象对应一类原生功能或系统接口。下面分门别类进行梳理。
1. plus.runtime:运行时环境
-
功能 :获取应用版本、App 的启动信息、退出重启 App、获取安装时间等。
-
常用属性与方法 :
- plus.runtime.version:返回运行时版本号。
- plus.runtime.appid:获取 App 的唯一标识。
- plus.runtime.quit():退出 App。
- plus.runtime.restart():重启 App。
- 示例 :
```js
console.log('当前 App 版本:', plus.runtime.version);
console.log('App ID:', plus.runtime.appid);
// 退出应用
// plus.runtime.quit();
2. plus.webview:多 WebView 管理
• 功能:管理应用中的多个 WebView,实现多页面间的跳转、交互、动画等。
• 核心概念:在 5+ 体系内,一个 App 可以包含多个 WebView,每个 WebView 都是一个子窗口,可单独加载页面或远程地址。
• 常用操作:
• plus.webview.create(url, id, styles, extras):创建新的 WebView 窗口。
• plus.webview.currentWebview():获取当前 WebView 对象。
• webview.show() / webview.hide() / webview.close():控制 WebView 的可见与销毁。
• webview.setStyle({...}):动态修改 WebView 样式。
• 示例:
const newWebview = plus.webview.create(
'exampleWebview',
{
top: '0px',
bottom: '0px',
render: 'always'
}
);
// 显示新 webview
newWebview.show('pop-in', 300);
3. plus.nativeUI:原生 UI 组件
• 功能:调用系统原生样式的 UI 组件,如 Alert、Confirm、Toast、ActionSheet 等。
• 常用方法:
• plus.nativeUI.alert(message, callback, title, buttonCaption):弹出原生 alert。
• plus.nativeUI.confirm(message, callback, title, buttonCaptions):原生 confirm 对话框。
• plus.nativeUI.toast(message, options):原生 toast 提示。
• plus.nativeUI.actionSheet(styles, callback):原生底部弹出菜单。
• 示例:
plus.nativeUI.alert('这是一个原生弹窗', () => {
console.log('用户点击了确定');
}, '提示', '确定');
4. plus.storage:本地存储
• 功能:提供一个键值对(Key-Value)形式的本地存储,容量更大、更适配移动端,与浏览器的 localStorage 类似,但更稳定。
• 常用方法:
• plus.storage.setItem(key, value)
• plus.storage.getItem(key)
• plus.storage.removeItem(key)
• plus.storage.clear()
• 示例:
plus.storage.setItem('username', 'Tom');
const username = plus.storage.getItem('username');
console.log('username:', username);
5. plus.io:文件系统
• 功能:读写本地文件、创建目录、删除文件等,提供对移动设备文件系统的访问。
• 常用目录:
• '_doc/':应用可读写的文档目录(Android 中通常是 /storage/emulated/0/Android/data/<包名>/Documents/;iOS 中是 Documents/ 目录)。
• '_downloads/':系统的下载目录,一般可读写。
• '_www/':打包进 App 的资源目录,只读。
• 常用方法:
• plus.io.resolveLocalFileSystemURL(path, successCallback, errorCallback):解析文件或目录的路径,获取对应的 Entry 对象。
• entry.file(successCallback, errorCallback):将文件转换为 File 对象,进而可用 FileReader 读取内容。
• entry.createWriter(successCallback, errorCallback):创建写入流,可写入文件。
• 示例(读取文件):
plus.io.resolveLocalFileSystemURL('_www/test.txt', function(entry) {
entry.file(function(file) {
const fileReader = new FileReader();
fileReader.onload = function(e) {
console.log('文件内容:', e.target.result);
};
fileReader.readAsText(file);
});
}, function(err) {
console.error('解析文件路径失败:', err);
});
• 示例(写入文件):
plus.io.resolveLocalFileSystemURL('_doc/', function(dirEntry) {
dirEntry.getFile('demo.txt', { create: true }, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.onwrite = function() {
console.log('写入成功');
};
writer.onerror = function(err) {
console.error('写入失败:', err);
};
writer.write('Hello from plus.io!');
});
});
});
6. plus.camera:相机功能
• 功能:调用设备摄像头拍照、录像。
• 常用方法:
• plus.camera.getCamera():获取摄像头对象。
• camera.captureImage(successCallback, errorCallback, options):拍照。
• camera.startVideoCapture(successCallback, errorCallback, options):录像。
• 示例(拍照):
const cmr = plus.camera.getCamera();
cmr.captureImage(function(path) {
console.log('拍照成功:', path);
// path 为临时路径,可移动到 _doc/ 等目录保存
}, function(err) {
console.error('拍照失败:', err);
}, {
filename: '_doc/camera/',
index: 1
});
7. plus.gallery:相册/图库功能
• 功能:从系统相册中选择图片或视频,也可保存图片到相册。
• 常用方法:
• plus.gallery.pick(successCallback, errorCallback, options):选择图片或视频。
• plus.gallery.save(path, successCallback, errorCallback):将图片保存到系统相册。
• 示例:
plus.gallery.pick(function(path) {
console.log('选择的文件路径:', path);
}, function(e) {
console.error('取消选择或失败:', e);
}, {
filter: 'image',
multiple: true,
maximum: 5
});
8. plus.uploader / plus.downloader:上传与下载
• 功能:基于原生的 HTTP 实现,支持断点续传、队列管理等。
• 常用方法:
• plus.uploader.createUpload(url, options, callback):创建上传任务。
• plus.downloader.createDownload(url, options, callback):创建下载任务。
• task.addFile(filePath, { key: 'file' }):为上传任务添加文件。
• task.start():开始上传/下载任务。
• task.addEventListener('statechanged', callback):监听任务进度。
• 示例(上传文件):
const uploadTask = plus.uploader.createUpload(
{ method: 'POST' },
function(upload, status) {
if (status === 200) {
console.log('上传成功:', upload.responseText);
} else {
console.log('上传失败,status = ' + status);
}
}
);
uploadTask.addFile('_doc/camera/test.jpg', { key: 'file' });
uploadTask.start();
9. plus.geolocation:地理定位
• 功能:使用 GPS 或网络定位获取地理坐标。
• 常用方法:
• plus.geolocation.getCurrentPosition(successCallback, errorCallback, options):获取当前位置。
• plus.geolocation.watchPosition(successCallback, errorCallback, options):持续监听位置变化。
• plus.geolocation.clearWatch(watchId):停止监听。
• 示例:
plus.geolocation.getCurrentPosition(function(position) {
console.log('经度:' + position.coords.longitude);
console.log('纬度:' + position.coords.latitude);
}, function(err) {
console.error('定位失败:', err);
}, {
enableHighAccuracy: true,
timeout: 10000
});
10. plus.key:物理按键
• 功能:监听设备上的物理按键,如返回键、菜单键等,尤其在 Android 上常见。
• 常用方法:
• plus.key.addEventListener(key, listener, capture):监听指定按键事件。
• plus.key.removeEventListener(key, listener):移除监听。
• 示例(监听返回键):
plus.key.addEventListener('backbutton', function() {
// 自定义返回逻辑,例如关闭 WebView
const current = plus.webview.currentWebview();
current.canBack(function(e) {
if (e.canBack) {
// 网页内可以回退
current.back();
} else {
// 网页内无回退,直接关闭
plus.runtime.quit();
}
});
});
11. plus.navigator:系统导航功能
• 功能:控制系统状态栏、全屏模式等。
• 常用方法:
• plus.navigator.setStatusBarStyle(style):设置状态栏文字颜色(如 "UIStatusBarStyleLightContent")。
• plus.navigator.setFullscreen(true):设置全屏显示。
• plus.navigator.isFullscreen():检查是否全屏。
12. plus.contacts:联系人操作
• 功能:读取、添加、修改手机通讯录联系人。
• 常用方法:
• plus.contacts.getAddressBook(type, successCB, errorCB):获取通讯录对象(分 SIM 卡或系统联系人等类型)。
• addressBook.find():查询联系人。
• addressBook.add():添加联系人。
• 注意:在某些系统上需要权限授权,或操作受限制。
13. plus.bluetooth:蓝牙功能
• 功能:扫描蓝牙设备、建立蓝牙连接、收发数据等。
• 常用方法:
• plus.bluetooth.openBluetoothAdapter():初始化本机蓝牙模块。
• plus.bluetooth.startBluetoothDevicesDiscovery():开始搜索附近设备。
• plus.bluetooth.connectBLEDevice():连接到某个 BLE 设备。
• plus.bluetooth.writeBLECharacteristicValue():写入特征值。
• plus.bluetooth.readBLECharacteristicValue():读取特征值。
• 注意:需要系统层面蓝牙权限,且仅支持低功耗蓝牙 BLE。
14. plus.push:推送功能
• 功能:接收 APNs(iOS)或第三方推送(Android)消息。
• 常用方法:
• plus.push.addEventListener("receive", callback):监听推送到达事件。
• plus.push.createMessage("内容", "msgid", {cover: false}):创建本地推送。
• 注意:远程推送需要在开发者后台配置证书/密钥,并在 App 端绑定推送通道。
15. 其他模块(plus.share, plus.pay, plus.audio, plus.accelerometer 等)
• plus.share:社会化分享,如分享到微信、微博、QQ 等平台,需要对应的插件或配置。
• plus.pay:原生支付通道,如支付宝、微信支付,需要对应的插件和签名配置。
• plus.audio:录音、播放音频。
• plus.accelerometer:获取加速度数据,实现摇一摇、运动监测等。
• ……
四、运行环境与 manifest.json 配置
- 运行环境
• plus 只在 App 端 或 HBuilderX 真机调试时有效。
• 如果在浏览器或小程序环境中预览,就拿不到 plus 对象。
- manifest.json
• manifest.json 是 App 的配置文件,用于声明 App 名称、图标、权限、SDK 配置等。
• 大多数与原生功能相关的权限(如相机、定位、推送)都需要在 manifest.json 中勾选或填入相应参数。
• 打包成正式 App 时,DCloud 的打包云服务或本地 cli 会读取 manifest.json,并在生成的原生项目中写入对应的系统配置文件(AndroidManifest.xml / Info.plist 等)。
五、plus 的使用姿势与注意事项
- 在 plusReady 回调里操作
• 当 WebView 环境初始化完成后,会触发 plusReady 事件。
• 最稳妥的方式是等 plusReady 后再去调用各种 plus.xxx。
• 例如:
document.addEventListener('plusready', function() {
// plus 对象已准备好
// 这里安全调用 plus.xxx
});
- 权限授权
• 访问相机、麦克风、定位等敏感功能,需要用户同意授权。
• iOS、Android 均有各自的权限管理流程,可能会弹出系统对话框。
• 如果用户拒绝授权,则相关功能将无法使用,需要处理好异常情况。
- 平台差异
• 部分 API 在 iOS 和 Android 上表现不同,或有兼容性差异。
• 需要在项目中做充分测试,尤其当你涉及到某些平台特有功能时。
- 结构与组织
• 如果项目非常庞大,可将 plus 相关调用集中封装在一个专用的模块或工具类中,并对外提供统一方法。
- 离线打包与在线资源
• App 发布时,可将部分 HTML/CSS/JS 资源打包进 _www,也可动态加载远程资源,或两者结合。
• 如果是远程资源,需要考虑无网络时的降级方案。
六、常见调试方法与排查技巧
- HBuilderX 真机/模拟器调试
• 通过 HBuilderX 的“运行到手机或模拟器”功能,实时查看调试控制台输出。
• 也可通过 Chrome DevTools (Android) 或 Safari (iOS) 进行远程调试。
- 远程调试
• 在 Android 上可通过 USB 连接手机后,打开 Chrome 地址栏输入 chrome://inspect 来调试。
• 在 iOS 上需先信任开发者证书,然后在 Safari 的“开发”菜单中找到对应设备进行调试。
- 捕获错误信息
• 使用全局捕获(如 window.onerror 或 Vue.config.errorHandler)来收集错误信息,避免遗漏。
• 在 plus 的异步回调中,也要注意写 errorCallback。
- 常见问题排查
• plus is not defined:环境不对,未在 App 端运行。
• 调用某功能无效:可能权限未声明或系统未授权。
• 读写文件失败:路径不正确,或无读写权限。
• 推送不起作用:证书/签名或服务端配置有问题。
七、性能与安全性
- 性能优化
• H5+ 内核在 UI 渲染、JS 解析 等方面已做大量原生层优化,性能优于传统 PhoneGap/Cordova。
• 多 WebView 并行处理,使页面切换更流畅。
• plus.cache 可以做文件缓存管理,也可手动管理 _doc/ 下的资源。
- 安全性
• 对敏感权限必须进行用户授权。
• JSBridge 仅对 plus 对象做了暴露,无法随意执行任意本地代码,避免潜在安全风险。
• DCloud 官方打包流程会对应用进行签名,保证发布渠道安全。
八、plus 与其他混合方案的对比
1. 与 Cordova / PhoneGap 的比较
• 相似点:都是通过 WebView + 原生插件的方式,向 JavaScript 暴露原生功能接口。
• 差异点:
• plus 是 DCloud 自研的 H5+ 引擎,内核深度优化,UI 交互更流畅。
• Cordova 提供大量第三方插件,但官方内核性能通常没有 DCloud 的 WebView 优化好。
• Cordova 需要自行配置 Android Studio / Xcode 项目,而 HBuilderX + plus 可以“一键打包”。
2. 与 Weex 的比较
• Weex:阿里主推的高性能跨平台方案,通过原生渲染来展示页面。
• 差异:
• plus 属于传统的“WebView + JSBridge”模式。
• Weex 通过一套渲染引擎将 Vue 语法转换为原生视图组件,理论上渲染性能更优,但生态配套相对复杂。
• uni-app 也曾使用过 Weex 作为渲染引擎之一,但目前官方更主推 WebView + V8 优化。
3. 与纯原生开发的比较
• 优势:
• 开发效率高、跨平台、维护成本低,前端工程师轻松上手。
• 劣势:
• 在特别复杂、极限性能的场景中,原生开发可能更灵活、更流畅。
• 不同机型或系统底层兼容性需要仔细测试。
九、生态与插件开发
1. 插件开发原理****
• plus 的插件机制依赖底层 JSBridge。
• 如果官方未提供你想要的原生能力,可以通过自定义插件编写原生代码(Android 的 Java/Kotlin,iOS 的 Objective-C/Swift),然后映射到 JavaScript。
2. 如何创建自定义插件
• 在 HBuilderX 中可以新建一个插件项目,编写 Android 与 iOS 端代码,并使用 DCloud 的插件打包工具打包。
• 打包生成的 .wgt 或 .wgtu 文件可被导入主应用,主应用就能调用插件暴露的 JS API。
• 也可以直接在 manifest.json 中声明插件包名,让云打包时自动集成插件。
3. 插件管理与版本更新
• DCloud 提供了 插件市场,许多常用的第三方功能(如极光推送、支付宝/微信等支付 SDK、语音识别等)都以插件方式上架。
• 开发者可在插件市场寻找所需插件,集成到项目里,定期更新插件版本以兼容新系统。
十、常见问题与疑难排查
- plus 对象无法使用
• 检查是否在 App 环境执行,或 document.addEventListener('plusready', ...)。
- 文件路径混乱
• 区分 _www, _doc, _documents, _downloads 等目录在不同系统上的映射位置。
• 注意 iOS 沙箱机制和 Android 文件系统差异。
- 权限相关错误
• iOS 需要在 manifest.json -> App 授权配置 中正确填写 NSCameraUsageDescription、NSLocationWhenInUseUsageDescription 等字段。
• Android 需要在 manifest.json 中勾选相机、读取存储等权限。
- 推送无法接收
• iOS 需要在开发者中心配置推送证书,Android 需要对应的厂商通道或第三方推送 SDK。
- 资源加载失败
• 若是网络请求,请确保网络权限与域名在 manifest.json 中做了允许访问配置。
• 本地资源要注意相对路径与 _www 的对应关系。
十一、总结
• plus 是 H5+ 的核心对象,由 DCloud 深度定制的 WebView 内核驱动,提供了大量原生接口,让前端开发者以较低门槛构建多功能移动 App。
• 通过 plus 可以访问文件系统、摄像头、定位、推送、支付、分享、蓝牙等能力,并在此基础上配合多 WebView 的管理,实现类原生的流畅体验。
• 使用 plus 需要在 App 环境下运行,注意权限、系统差异、调试方式等;并配合 manifest.json 做好配置,合理封装代码结构可让项目更加健壮。
• 若官方接口不足,可自行开发原生插件,或从插件市场获取更多能力。
• 对于需要支持多端(App、小程序、H5)的项目,uni-app + plus 是主流组合,可在 App 端实现原生能力,在小程序端采用对应的小程序 API,在 H5 端则自动降级或使用浏览器特性。
通过对以上内容的深入理解和灵活运用,相信你能更好地利用 plus(H5+)构建出体验优异、功能完善的移动 App。