Skip to content

原生模块及插件

VIP 用户可以在 uniapp 项目中集成和使用原生模块及插件,扩展应用的原生能力。

概述

什么是原生模块

原生模块是使用平台原生语言(Java/Kotlin 或 Swift/Objective-C)开发的功能模块,可以访问系统底层 API 和第三方 SDK。

使用场景

  • 📷 使用特定相机 SDK
  • 📊 集成数据统计分析
  • 💳 接入支付 SDK
  • 🗺️ 使用地图服务
  • 📞 调用系统通讯录
  • 🔐 实现生物识别
  • 🎵 音视频处理
  • 📡 蓝牙/NFC 通信

插件市场

浏览插件

  1. 访问插件市场

    在工具中:

  2. 搜索插件

    支持按以下条件搜索:

    • 关键词
    • 分类(支付、地图、推送等)
    • 平台(Android/iOS/全平台)
    • 评分和下载量
  3. 查看插件详情

    每个插件包含:

    • 功能说明
    • 使用文档
    • 示例代码
    • 兼容性说明
    • 用户评价

安装插件

方式一:通过市场安装

  1. 在插件详情页点击"安装"
  2. 选择要安装到的项目
  3. 确认插件配置
  4. 等待自动下载和集成

方式二:手动安装

  1. 下载插件包(.zip 文件)
  2. 解压到项目的 nativeplugins 目录
  3. manifest.json 中配置插件

配置插件

manifest.json 中添加插件配置:

json
{
  "nativePlugins": {
    "plugin-name": {
      "type": "native",
      "parameters": {
        "appKey": "your_app_key",
        "appSecret": "your_app_secret"
      }
    }
  }
}

使用插件

在代码中调用插件:

javascript
// 引入插件
const plugin = uni.requireNativePlugin('plugin-name')

// 调用插件方法
plugin.methodName({
  param1: 'value1',
  param2: 'value2'
}, (result) => {
  if (result.success) {
    console.log('成功:', result.data)
  } else {
    console.error('失败:', result.error)
  }
})

常用插件示例

1. 支付宝支付

安装:

在插件市场搜索"支付宝支付"并安装。

配置:

json
{
  "nativePlugins": {
    "uniapp-alipay": {
      "parameters": {
        "appId": "your_alipay_app_id"
      }
    }
  }
}

使用:

javascript
const alipay = uni.requireNativePlugin('uniapp-alipay')

// 发起支付
alipay.pay({
  orderInfo: 'your_order_info_string'
}, (res) => {
  if (res.resultStatus === '9000') {
    console.log('支付成功')
  } else {
    console.log('支付失败或取消')
  }
})

2. 高德地图

安装:

搜索"高德地图"插件。

配置:

json
{
  "nativePlugins": {
    "uniapp-amap": {
      "parameters": {
        "ios_key": "your_ios_key",
        "android_key": "your_android_key"
      }
    }
  }
}

使用:

javascript
const amap = uni.requireNativePlugin('uniapp-amap')

// 显示地图
amap.showMap({
  latitude: 39.908823,
  longitude: 116.397470,
  zoom: 15
})

// 添加标记
amap.addMarker({
  latitude: 39.908823,
  longitude: 116.397470,
  title: '天安门',
  snippet: '北京市中心'
})

3. 极光推送

配置:

json
{
  "nativePlugins": {
    "jpush": {
      "parameters": {
        "appKey": "your_jpush_key"
      }
    }
  }
}

使用:

javascript
const jpush = uni.requireNativePlugin('jpush')

// 设置别名
jpush.setAlias({
  alias: 'user_123'
}, (res) => {
  console.log('设置别名:', res)
})

// 监听通知
jpush.addListener('receiveNotification', (notification) => {
  console.log('收到通知:', notification)
})

4. 指纹识别

使用:

javascript
const fingerprint = uni.requireNativePlugin('fingerprint')

// 验证指纹
fingerprint.authenticate({
  title: '指纹验证',
  subtitle: '请验证您的指纹',
  description: '触摸指纹传感器'
}, (res) => {
  if (res.success) {
    console.log('指纹验证成功')
  } else {
    console.error('验证失败:', res.error)
  }
})

自定义原生模块

Android 模块开发

1. 创建 Android 模块

在 Android Studio 中创建新模块:

项目结构:
android-module/
├── src/
│   └── main/
│       ├── java/
│       │   └── com/example/module/
│       │       └── MyModule.java
│       └── AndroidManifest.xml
└── build.gradle

2. 实现模块

java
package com.example.module;

import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class MyModule extends UniModule {

    @UniJSMethod(uiThread = false)
    public void sayHello(String name, UniJSCallback callback) {
        if (callback != null) {
            JSONObject result = new JSONObject();
            try {
                result.put("message", "Hello, " + name + "!");
                callback.invoke(result);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    @UniJSMethod(uiThread = true)
    public void showToast(String message) {
        Toast.makeText(mUniSDKInstance.getContext(),
                      message,
                      Toast.LENGTH_SHORT).show();
    }
}

3. 注册模块

AndroidManifest.xml 中:

xml
<meta-data
    android:name="my-module"
    android:value="com.example.module.MyModule" />

4. 打包模块

gradle
// build.gradle
apply plugin: 'com.android.library'

android {
    compileSdkVersion 33

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 33
    }
}

dependencies {
    compileOnly 'io.dcloud:uniapp:3.0.0'
}

构建 AAR:

bash
./gradlew assembleRelease

iOS 模块开发

1. 创建 iOS 模块

在 Xcode 中创建静态库项目:

项目结构:
ios-module/
├── MyModule.h
├── MyModule.m
└── Info.plist

2. 实现模块

objective-c
// MyModule.h
#import <Foundation/Foundation.h>
#import "UniPluginProtocol.h"

@interface MyModule : NSObject <UniModuleProtocol>
@end

// MyModule.m
#import "MyModule.h"

@implementation MyModule

UNI_EXPORT_METHOD(@selector(sayHello:callback:))
- (void)sayHello:(NSDictionary *)params callback:(UniModuleKeepAliveCallback)callback {
    NSString *name = params[@"name"];
    NSString *message = [NSString stringWithFormat:@"Hello, %@!", name];

    if (callback) {
        callback(@{@"message": message}, NO);
    }
}

UNI_EXPORT_METHOD(@selector(showToast:))
- (void)showToast:(NSString *)message {
    dispatch_async(dispatch_get_main_queue(), ^{
        // 显示 Toast
        UIAlertController *alert = [UIAlertController
            alertControllerWithTitle:nil
            message:message
            preferredStyle:UIAlertControllerStyleAlert];

        UIViewController *rootVC = [UIApplication sharedApplication]
            .keyWindow.rootViewController;
        [rootVC presentViewController:alert animated:YES completion:^{
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC),
                          dispatch_get_main_queue(), ^{
                [alert dismissViewControllerAnimated:YES completion:nil];
            });
        }];
    });
}

@end

3. 注册模块

在模块的配置文件中:

json
{
  "name": "my-module",
  "class": "MyModule",
  "type": "module"
}

4. 打包模块

在 Xcode 中:

  1. 选择 Product > Build For > Running
  2. 生成 .a 静态库文件
  3. 导出 Header 文件

集成第三方 SDK

Android SDK 集成

1. 添加依赖

在模块的 build.gradle 中:

gradle
dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'
    implementation 'com.google.code.gson:gson:2.8.9'
}

2. 封装 SDK

java
public class MySDKModule extends UniModule {

    private OkHttpClient client = new OkHttpClient();

    @UniJSMethod
    public void httpRequest(JSONObject options, UniJSCallback callback) {
        String url = options.optString("url");

        Request request = new Request.Builder()
            .url(url)
            .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    String body = response.body().string();
                    JSONObject result = new JSONObject();
                    result.put("data", body);
                    callback.invoke(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call call, IOException e) {
                JSONObject error = new JSONObject();
                try {
                    error.put("error", e.getMessage());
                    callback.invoke(error);
                } catch (JSONException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }
}

iOS SDK 集成

1. 添加依赖

使用 CocoaPods:

ruby
# Podfile
pod 'Alamofire', '~> 5.0'
pod 'SwiftyJSON', '~> 5.0'

2. 封装 SDK

swift
import Alamofire

@objc(MySDKModule)
class MySDKModule: NSObject, UniModuleProtocol {

    @objc func httpRequest(_ params: [String: Any], callback: @escaping UniModuleKeepAliveCallback) {
        guard let url = params["url"] as? String else {
            callback(["error": "URL is required"], false)
            return
        }

        AF.request(url).responseString { response in
            switch response.result {
            case .success(let value):
                callback(["data": value], false)
            case .failure(let error):
                callback(["error": error.localizedDescription], false)
            }
        }
    }
}

模块调试

Android 调试

  1. 连接设备
bash
adb devices
  1. 查看日志
bash
adb logcat | grep "MyModule"
  1. 调试输出
java
Log.d("MyModule", "Debug message");

iOS 调试

  1. 在 Xcode 中运行

    • 选择设备或模拟器
    • 点击 Run
  2. 查看日志

objective-c
NSLog(@"Debug message: %@", data);
  1. 断点调试

    在 Xcode 中设置断点,单步调试。


发布模块

准备发布

  1. 编写文档

    • README.md
    • 使用示例
    • API 文档
  2. 准备资源

    • 模块图标
    • 截图
    • 演示视频
  3. 打包文件

plugin-package/
├── android/
│   └── module.aar
├── ios/
│   ├── module.a
│   └── headers/
├── package.json
├── README.md
└── example/

提交到插件市场

  1. 登录插件市场
  2. 点击"发布插件"
  3. 填写插件信息:
    • 名称和描述
    • 分类和标签
    • 平台支持
    • 价格(免费/付费)
  4. 上传插件包
  5. 提交审核

常见问题

模块加载失败

问题: 提示找不到模块

解决方案:

  1. 检查 manifest.json 配置
  2. 确认模块文件在正确位置
  3. 重新编译项目
  4. 查看错误日志

方法调用失败

问题: 调用模块方法无响应

解决方案:

  1. 检查方法名是否正确
  2. 确认参数格式正确
  3. 查看是否有错误回调
  4. 检查线程设置(UI/非UI)

依赖冲突

问题: 多个插件依赖同一库的不同版本

解决方案:

  1. 统一依赖版本
  2. 使用依赖排除
  3. 升级到兼容版本

最佳实践

1. 错误处理

始终提供错误回调:

javascript
plugin.method({}, (res) => {
  if (res.error) {
    console.error('Error:', res.error)
    return
  }
  console.log('Success:', res.data)
})

2. 异步操作

耗时操作使用异步:

java
@UniJSMethod(uiThread = false)
public void longOperation(UniJSCallback callback) {
    // 耗时操作
}

3. 资源释放

及时释放资源:

objective-c
- (void)dealloc {
    // 清理资源
    [self cleanup];
}

4. 权限检查

使用权限前先检查:

java
if (ContextCompat.checkSelfPermission(context,
    Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
    // 请求权限
}

下一步

了解了原生模块后,您可以:

Released under the MIT License.