文章目錄
- 前言
- ? 1. App 使用的 Runtime 架構:**WebView + 原生容器(plus runtime)**
- 📌 技術棧核心:
- ? 2. WebView + Native 的通信機制詳解(JSBridge)
- 📤 Web → Native 調用(JS 調原生)
- 📥 Native → Web 回調
- ? 3. App 平臺打包說明
- ? 4. uni-app 的 App 通信示意圖:
- 🧠 補充說明
- ? 一、前端 JS 調用 Native 插件示例
- ? 二、Android 插件實現(Java)
- 📄 1. 創建插件類:`MyPlugin.java`
- 📄 2. 插件注冊(`AndroidManifest.xml`)
- ? 三、iOS 插件實現(Swift)
- 📄 1. 創建插件類:`MyPlugin.swift`
- 📄 2. 插件注冊
- ? 四、文件結構建議(uni\_modules)
- 📄 `main.js` 示例
- ? 五、注意事項
前言
在 uni-app 中適配 App 平臺(即打包生成 iOS/Android 原生應用)時,使用的是一種混合開發架構(Hybrid App Runtime),其核心是:
? 1. App 使用的 Runtime 架構:WebView + 原生容器(plus runtime)
📌 技術棧核心:
- 前端代碼運行在 WebView 中(HTML + CSS + JS 渲染);
- 原生能力(攝像頭、定位、藍牙、支付等)通過
plus.*
API 調用; - Web 層與 Native 層之間通過 JSBridge 通信機制 實現雙向調用;
這類架構被稱為“HTML5+ Runtime”,是 DCloud 自研的一種 增強型 WebView 容器。
? 2. WebView + Native 的通信機制詳解(JSBridge)
📤 Web → Native 調用(JS 調原生)
- 使用
plus.xxx
(如plus.camera.getCamera()
)來發起調用; - DCloud 注入了
plus
對象到 WebView 的 JS 全局作用域; - JS 觸發調用 → Native 捕捉到請求 → 執行原生功能 → 可異步返回結果到 JS。
📥 Native → Web 回調
- 原生模塊執行完成后,通過
evalJS()
或postMessage()
回調到 Web; - uni-app 框架統一管理回調,開發者通常不需要手動維護 bridge 通道。
? 3. App 平臺打包說明
平臺 | 說明 |
---|---|
Android | 使用 Android WebView + Java 實現容器,集成 H5+ SDK。\n打包工具:HBuilderX、CLI 構建 App 包(.apk) |
iOS | 使用 WKWebView + Objective-C 實現容器,集成 H5+ SDK。\n打包生成 .ipa 包,支持上架 App Store |
plus API | 統一封裝攝像頭、位置、文件系統、藍牙、推送、支付等原生能力 |
Native 插件 | 可編寫自定義原生插件,使用 Java(Android)或 Swift(iOS)開發,通過 JSBridge 調用 |
? 4. uni-app 的 App 通信示意圖:
[ WebView 頁面(Vue) ]↓ JS 調用[ plus.xxx API ]↓
[ JSBridge 通道 ]↓
[ 原生模塊(如 Camera、Push、BLE) ]↑結果回調通過 JSBridge → JS
🧠 補充說明
項目 | uni-app App 平臺表現 |
---|---|
性能 | 基于 WebView,復雜場景性能略遜于原生,但普通業務流暢運行無礙 |
原生擴展 | 支持自定義 Native 插件 + 云插件市場 |
通信機制 | 類似于 React Native 的 bridge,不過由 DCloud 完全封裝,對開發者透明 |
安全 | plus API 具備權限校驗機制,需在 manifest.json 配置權限聲明 |
完整示例,展示在 uni-app 中的 App 端如何通過 JS 與 Native 插件(Java/Android 或 Swift/iOS)進行通信,包括:
- 前端 JS 如何調用原生方法;
- Android 原生插件如何實現;
- iOS 原生插件如何實現;
- 插件注冊與 manifest 配置說明。
? 一、前端 JS 調用 Native 插件示例
// 調用自定義插件 myPlugin.hello
uni.callNativePlugin('myPlugin', 'hello', { name: 'IT iPower' }, res => {console.log('原生返回結果:', res)
})
? 也可以使用 uniModules 提供的 Promise 封裝方式(推薦):
import MyPlugin from '@/uni_modules/myPlugin/js_sdk/main.js'MyPlugin.hello({ name: 'IT iPower' }).then(res => {console.log('調用成功', res)
})
? 二、Android 插件實現(Java)
📄 1. 創建插件類:MyPlugin.java
package io.dcloud.uniapp.plugins;import android.content.Context;
import android.widget.Toast;import org.json.JSONObject;import io.dcloud.feature.uniapp.common.UniModule;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;public class MyPlugin extends UniModule {@UniJSMethod(uiThread = true)public void hello(JSONObject options) {String name = options.optString("name", "世界");Toast.makeText(mUniSDKInstance.getContext(), "你好," + name, Toast.LENGTH_SHORT).show();// 向 JS 回傳值(如有回調)JSONObject result = new JSONObject();try {result.put("msg", "來自 Android 原生的問候");} catch (Exception e) {}this.invokeCallback(options, result);}
}
📌 說明:使用
@UniJSMethod
注解的方法可在 JS 中被調用。
📄 2. 插件注冊(AndroidManifest.xml
)
<service android:name="io.dcloud.uniapp.plugins.MyPlugin" />
或者在 manifest.json
的 app-plus.modules
中聲明:
"app-plus": {"modules": {"myPlugin": "io.dcloud.uniapp.plugins.MyPlugin"}
}
? 三、iOS 插件實現(Swift)
📄 1. 創建插件類:MyPlugin.swift
import Foundation
import UIKit@objc(MyPlugin)
class MyPlugin: NSObject {@objc func hello(_ options: NSDictionary, callback: @escaping FlutterResult) {let name = options["name"] as? String ?? "世界"DispatchQueue.main.async {let alert = UIAlertController(title: "Hello", message: "你好,\(name)", preferredStyle: .alert)alert.addAction(UIAlertAction(title: "OK", style: .default))UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)}let result: [String: Any] = ["msg": "來自 iOS 原生的問候"]callback(result)}
}
📄 2. 插件注冊
在 manifest.json
中配置模塊映射:
"app-plus": {"modules": {"myPlugin": "MyPlugin"}
}
? 四、文件結構建議(uni_modules)
uni_modules/
└── myPlugin/├── js_sdk/│ └── main.js // JS SDK 封裝調用├── android/│ └── MyPlugin.java├── ios/│ └── MyPlugin.swift└── manifest.json // 插件聲明
📄 main.js
示例
function hello(data = {}) {return new Promise((resolve, reject) => {uni.callNativePlugin('myPlugin', 'hello', data, res => {resolve(res)})})
}export default {hello
}
? 五、注意事項
項目 | 說明 |
---|---|
HBuilderX 調試 | 支持真機調試原生插件,使用“運行到手機” |
自定義插件封裝建議 | 使用 uni_modules 統一結構 |
插件通信安全注意 | 參數校驗、平臺判斷、異常處理 |
插件分發 | 可上傳到 DCloud 插件市場 |