当前位置: 首页 > news >正文

uni-app 自定义 Android 插件详解

文章目录

  • uni-app 自定义 Android 插件详解
    • 一、准备工作
    • 二、创建插件目录结构
    • 三、编写 `package.json`
    • 四、编写 Android 原生代码 (Java)
      • 1. 创建插件类 `MyAwesomePlugin.java`
      • 2. `AndroidManifest.xml` (可选)
      • 3. `build.gradle` (可选)
    • 五、编写 JS 接口 (`index.js`)
    • 六、在 uni-app 项目中使用插件
    • 七、关键概念与最佳实践
    • 八、总结

uni-app 自定义 Android 插件详解

在 uni-app 开发中,当内置 API 无法满足需求时(如调用特定硬件、集成第三方 SDK),就需要开发 自定义 Android 原生插件。这允许你使用 Java/Kotlin 编写原生代码,并通过 JavaScript 接口在 uni-app 中调用。


一、准备工作

  1. 开发环境:
    • HBuilderX (推荐使用最新版)
    • Android Studio
    • JDK
    • Android SDK
  2. 项目结构:
    • uni-app 项目根目录
    • nativeplugins/ 目录 (手动创建):存放所有自定义原生插件。

二、创建插件目录结构

nativeplugins/ 下创建插件文件夹,结构如下:


nativeplugins/
└── my-awesome-plugin/          # 插件根目录 (命名规范: 小写字母、数字、下划线)
├── android/               # Android 原生代码
│   ├── src/
│   │   └── main/
│   │       ├── java/      # Java/Kotlin 源码
│   │       │   └── com/
│   │       │       └── dcloud/
│   │       │           └── plugin/
│   │       │               └── MyAwesomePlugin.java  # 核心插件类
│   │       ├── AndroidManifest.xml  # 插件清单文件
│   │       └── assets/    # 资源文件 (可选)
│   └── build.gradle       # 插件构建脚本
├── package.json           # 插件描述文件 (必须)
└── index.js               # JS 调用接口 (可选,推荐)

三、编写 package.json

这是插件的核心描述文件,uni-app 通过它识别插件。

{"id": "my-awesome-plugin",          // 插件唯一标识 (与目录名一致)"displayName": "我的插件",      		// 插件名称 (HBuilderX 中显示)"version": "1.0.0",                 // 版本号"description": "一个演示自定义插件的示例", // 描述"platforms": {"Android": ">=3.0.0"             // 支持的平台和最低 uni-app 版本},"engines": {"HBuilderX": ">=3.0.0"           // 最低 HBuilderX 版本},"permissions": ["Camera",                        // 需要的权限 (会自动合并到主应用)"Storage"],"hooks": [],                        // 钩子 (较少用)"nativePlugins": [{"type": "module",               // 类型: module (功能模块)"name": "MyAwesomePlugin",      // 模块名 (JS 中调用的名称)"android": {"plugins": [{"type": "service",        // 插件类型: service (服务类)"name": "MyAwesomePlugin", // Java 类名 (不含包名)"class": "com.dcloud.plugin.MyAwesomePlugin" // 完整类名}]}}]
}

四、编写 Android 原生代码 (Java)

1. 创建插件类 MyAwesomePlugin.java

该类必须继承 io.dcloud.feature.uniapp.common.UniModule


package com.dcloud.plugin;import android.util.Log;
import android.widget.Toast;
import io.dcloud.feature.uniapp.annotation.UniJSMethod; // 注解: 标记 JS 可调用方法
import io.dcloud.feature.uniapp.common.UniModule;
import io.dcloud.feature.uniapp.ui.view.WebView;public class MyAwesomePlugin extends UniModule {private static final String TAG = "MyAwesomePlugin";// JS 调用的方法必须用 @UniJSMethod 注解// mode = UniJSMethod.THREAD_UI: 在 UI 线程执行 (用于更新 UI)// mode = UniJSMethod.THREAD_MAIN: 在主线程执行 (默认)@UniJSMethod(uiThread = true)public void showToast(String message, int duration, UniCallback callback) {Log.d(TAG, "收到 JS 消息: " + message);// 在 UI 线程执行 ToastToast.makeText(mWXSDKInstance.getContext(), message, duration == 1 ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();// 调用 callback 通知 JS 任务完成 (可选)if (callback != null) {// 返回给 JS 的数据UniMPJSResponse response = new UniMPJSResponse();response.setData("Toast 显示成功: " + message);response.setSuccess(true);callback.invoke(response);}}@UniJSMethodpublic void getDeviceInfo(UniCallback callback) {try {JSONObject deviceInfo = new JSONObject();deviceInfo.put("model", Build.MODEL);deviceInfo.put("brand", Build.BRAND);deviceInfo.put("version", Build.VERSION.RELEASE);UniMPJSResponse response = new UniMPJSResponse();response.setData(deviceInfo);response.setSuccess(true);callback.invoke(response);} catch (Exception e) {UniMPJSResponse response = new UniMPJSResponse();response.setSuccess(false);response.setMsg(e.getMessage());callback.invoke(response);}}// UniModule 提供的上下文// mWXSDKInstance.getContext() 获取 Context
}

2. AndroidManifest.xml (可选)

如果插件需要声明 Activity、Service 或特殊权限,需在此文件中定义。


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><!-- 插件所需的权限 (如果 package.json 中已声明,可省略) --><!-- <uses-permission android:name="android.permission.CAMERA"/> --><!-- 如果需要启动 Activity --><!-- <activity android:name=".MyPluginActivity" /> --></manifest>

3. build.gradle (可选)

如果插件依赖第三方库,则需要此文件。


dependencies {implementation 'com.squareup.okhttp3:okhttp:4.9.3'// 添加其他依赖...
}

五、编写 JS 接口 (index.js)

提供一个更友好的 JavaScript 接口给开发者。


// nativeplugins/my-awesome-plugin/index.js// 导出方法
export function showToast(message, duration = 0) {// uni.requireNativePlugin 返回原生模块实例const MyAwesomePlugin = uni.requireNativePlugin('MyAwesomePlugin');return new Promise((resolve, reject) =&gt; {MyAwesomePlugin.showToast(message, duration, (result) =&gt; {if (result.success) {resolve(result.data);} else {reject(new Error(result.msg || '调用失败'));}});});
}export function getDeviceInfo() {const MyAwesomePlugin = uni.requireNativePlugin('MyAwesomePlugin');return new Promise((resolve, reject) =&gt; {MyAwesomePlugin.getDeviceInfo((result) =&gt; {if (result.success) {resolve(result.data);} else {reject(new Error(result.msg));}});});
}

六、在 uni-app 项目中使用插件

  1. HBuilderX 识别: 重启 HBuilderX,插件会自动被识别。
  2. 引用 JS 接口:

<template><view><button @click="handleClick">调用原生插件</button></view>
</template><script>
// 引入封装好的 JS 接口
import { showToast, getDeviceInfo } from '@/nativeplugins/my-awesome-plugin/index.js'export default {methods: {async handleClick() {try {// 调用 showToastawait showToast('Hello from Native!', 1);// 调用 getDeviceInfoconst info = await getDeviceInfo();console.log('设备信息:', info);} catch (error) {console.error('插件调用失败:', error);}}}
}
</script>

七、关键概念与最佳实践

  1. @UniJSMethod 注解:

    • 标记 Java 方法可被 JS 调用。
    • uiThread = true: 方法在 UI 线程执行,用于更新 UI (如 Toast, Dialog)。
    • callback: JS 调用时传入的回调函数,在原生方法执行完毕后调用它返回结果。
  2. 线程安全:

    • 默认在主线程执行。
    • 耗时操作(网络、数据库)必须在子线程中进行,避免阻塞。
    • 更新 UI 必须回到 UI 线程 (uiThread = true 或使用 runOnUiThread)。
  3. 权限处理:

    • package.jsonpermissions 中声明。
    • Android 6.0+ 需要运行时动态申请权限。可在插件中使用 mWXSDKInstance.getActivity() 获取 Activity 实例来申请。
  4. 调试:

    • Java 代码: 使用 Android Studio 打开 unpackage 目录下的原生工程进行调试。
    • 日志: 使用 Log.d() 输出日志,在 Android Studio 的 Logcat 中查看。
    • JS 代码: 使用 console.log
  5. 打包:

    • 在 HBuilderX 中正常打包 App。
    • 插件代码会被自动集成到原生工程中。
  6. 错误处理:

    • 原生代码中捕获异常,通过 callback 返回错误信息给 JS。
    • JS 端使用 try-catch.catch() 处理 Promise 错误。

八、总结

开发 uni-app 自定义 Android 插件的核心流程:

  1. 创建结构: nativeplugins/your-plugin/ 目录。
  2. 编写 package.json: 描述插件元信息。
  3. 编写 Java 类: 继承 UniModule,用 @UniJSMethod 标记方法。
  4. (可选) 编写 index.js: 提供友好的 JS API。
  5. 在项目中使用: 通过 uni.requireNativePlugin 或导入 index.js 调用。

自定义插件是扩展 uni-app 能力的关键,掌握它能让你的跨平台应用实现几乎任何原生功能。

http://www.dtcms.com/a/410104.html

相关文章:

  • Spring IOC源码篇五 核心方法obtainFreshBeanFactory.doLoadBeanDefinitions
  • kafka和rocketmq的副本机制区别: isr 主从模式,Dledger模式
  • HTTP的持续与非持续连接,HTTP报文格式
  • 删除Notepad++关于弹窗的反动字样
  • angular2是做网站的还是手机的网站开发大概价格
  • 国内专业做悬赏的网站绵阳网站建设设计
  • 抗辐照MCU芯片在核工业水下探测耐辐照数字摄像机中的应用研究
  • 《测试视角下的软件工程:需求、开发模型与测试模型》
  • 电子证照系统国产化改造实践:从MongoDB到金仓数据库的平滑迁移与性能优化
  • 开源的容器化平台:Docker
  • 【Prompt学习技能树地图】思维链(CoT)提示技术工作原理、主要技术方法及实践应用
  • 谁有手机可以上的网站网站建设 部署与发布视频
  • 【足式机器人算法】#1 强化学习基础
  • Maven的概述/简介/安装/基本使用/IDE配置/依赖管理
  • 构建 maven:3.8.7-jdk17 镜像
  • maven install依赖后 另一个项目 maven reload找不到包
  • 北京做网站的网络公司新网站改关键词
  • SpringCloud 项目阶段十:kafka实现双端信息同步以及ElasticSearch容器搭建示例
  • 解析前端框架 Axios 的设计理念与源码:从零手写一个支持 HTTP/3 的“类 Axios”最小核
  • 共享ip服务器做网站小型创意电子产品设计
  • [Dify] 知识库架构介绍与使用场景概述
  • NFS 服务器iSCSI 服务器
  • 如何确保CMS系统能够快速响应用户请求?全面性能优化指南
  • 【202509新版】Hexo + GitHub Pages 免费部署个人博客|保姆级教程 第三部
  • 同时使用ReactUse 、 ahooks与性能优化
  • 跨境电商怎么做一件代发宁波关键词排名优化平台
  • FreeFusion:基于交叉重构学习的红外与可见光图像融合
  • GraphRAG对自然语言处理中深层语义分析的革命性影响与未来启示
  • 数据分析-60-工业时序数据分析之开关频次
  • C++入门基础知识157—【用一篇博文简单了解数据结构之红黑树】