1. 为什么需要uni-app安卓原生插件
当你用uni-app开发跨平台应用时,90%的功能都能用H5实现。但总有些场景需要调用手机原生能力,比如:
- 调用手机传感器(陀螺仪、NFC)
- 集成第三方SDK(人脸识别、支付)
- 实现高性能计算(图像处理)
这时候就需要开发原生插件。我去年做过一个运动类APP,需要实时获取步数数据。H5的计步API在iOS上能用,但在安卓机型上兼容性极差,最后就是通过开发原生插件解决的。
原生插件本质上是个桥梁,让JS能调用Java代码。uni-app支持两种插件模式:
- Module模式:适合功能扩展(比如调用系统API)
- Component模式:适合嵌入原生UI(比如地图组件)
提示:大部分场景用Module模式就够了,只有需要嵌入原生UI时才用Component模式
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境搭建实战
2.1 必备工具清单
- Android Studio 2022+(建议下载最新稳定版)
- HBuilderX 3.6+(uni-app官方IDE)
- JDK 11(注意不要用JDK 17,会有兼容问题)
我第一次配置环境时踩过坑:Android Studio的Gradle版本和项目不匹配,导致编译失败。建议直接用uni-app提供的离线SDK里的示例工程,能省去很多配置麻烦。
2.2 项目结构解析
下载的SDK包含:
code复制UniPlugin-Hello-AS/
├── app/ # 主模块
├── library/ # 插件模块示例
└── UniPlugin-Hello-AS.iml
重点看library模块,这是插件开发的核心。我建议直接复制这个模块进行改造,比从零新建更稳妥。
3. 开发第一个Module插件
3.1 创建插件模块
- 在Android Studio右键项目 → New → Module
- 选择
Android Library,命名如pedometer-plugin - 修改
build.gradle关键配置:
groovy复制dependencies {
compileOnly 'androidx.appcompat:appcompat:1.6.1'
compileOnly 'com.alibaba:fastjson:1.2.83'
compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')
}
用compileOnly避免依赖冲突,这是很多新手容易忽略的点。
3.2 编写核心逻辑
创建StepCounterModule.java:
java复制public class StepCounterModule extends UniModule {
@UniJSMethod(uiThread = true)
public void startCounting(JSONObject params, UniJSCallback callback) {
// 获取系统计步服务
SensorManager manager = (SensorManager) mUniSDKInstance.getContext()
.getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = manager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
// 回调步数数据
JSONObject result = new JSONObject();
result.put("steps", 1024);
callback.invoke(result);
}
}
注意三个关键点:
- 必须继承
UniModule - 方法要用
@UniJSMethod注解 - 回调数据用
UniJSCallback
3.3 注册插件
在assets目录新建dcloud_uniplugins.json:
json复制{
"nativePlugins": [{
"plugins": [{
"type": "module",
"name": "StepCounter",
"class": "com.your.package.StepCounterModule"
}]
}]
}
这里有个易错点:json文件必须用UTF-8编码,否则云打包时会解析失败。
4. 本地调试技巧
4.1 uni-app端调用
在vue文件中:
javascript复制const stepCounter = uni.requireNativePlugin('StepCounter')
stepCounter.startCounting({}, res => {
console.log('今日步数:', res.steps)
})
4.2 真机调试流程
- 在HBuilderX生成调试包:
发行 → 原生App-本地打包 → 生成资源 - 将
assets文件夹复制到Android项目的main目录 - 连接手机开启USB调试,点击Android Studio的Run按钮
我习惯在插件方法里加Log输出:
java复制Log.d("StepCounter", "收到JS调用:" + options.toString());
这样在Android Studio的Logcat里能实时看到调用日志。
5. 云打包与上架指南
5.1 生成aar文件
- 在Gradle面板找到
:your_module → Tasks → build → assembleRelease - 生成的aar位于
/build/outputs/aar/your_module-release.aar
5.2 uni-app项目集成
- 创建项目结构:
code复制nativeplugins/
└── StepCounter/
├── android/
│ └── your_module-release.aar
└── package.json
- 配置
package.json:
json复制{
"name": "StepCounter",
"id": "StepCounter",
"version": "1.0.0",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"integrateType": "aar",
"plugins": [{
"type": "module",
"name": "StepCounter",
"class": "com.your.package.StepCounterModule"
}]
}
}
}
5.3 常见打包问题
-
问题1:
Minimum SDK version too high
解决方案:在AndroidManifest.xml添加:xml复制<uses-sdk tools:overrideLibrary="com.your.package" /> -
问题2:
Duplicate class found
这是因为依赖冲突,把所有依赖改为compileOnly即可
5.4 发布到DCloud市场
- 压缩插件目录为zip文件
- 登录插件市场
- 上传时注意:
- 插件ID必须与package.json一致
- 需要提供详细的README.md
- 建议附带demo项目
我在第一次发布时因为没写清楚使用文档被退回三次,后来总结出文档要包含:
- 功能说明
- 集成步骤
- API文档
- 常见问题
6. 高级开发技巧
6.1 性能优化建议
- 耗时操作要设置
uiThread = false - 避免频繁JS-native通信
- 使用对象池复用Java对象
6.2 复杂参数处理
当需要传递复杂数据时,建议用JSON序列化:
java复制@UniJSMethod(uiThread = false)
public JSONObject getDeviceInfo() {
JSONObject info = new JSONObject();
info.put("model", Build.MODEL);
info.put("sdk", Build.VERSION.SDK_INT);
return info;
}
6.3 生命周期管理
重写这些方法处理资源释放:
java复制@Override
public void onActivityDestroy() {
// 释放传感器等资源
sensorManager.unregisterListener(this);
}
7. 项目实战经验
去年开发蓝牙插件时遇到个典型问题:Android不同版本API差异大。最后通过版本判断解决:
java复制@UniJSMethod(uiThread = true)
public void connectBluetooth(JSONObject params) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 用新的API
} else {
// 兼容旧版本
}
}
另一个经验是做好错误处理:
java复制try {
// 可能出错的操作
} catch (Exception e) {
callback.invokeAndKeepAlive(new JSONObject() {{
put("code", "error");
put("message", e.getMessage());
}});
}
