背景
使用 uniapp 开发应用时,很多时候都需要调用第三方的sdk,一般以 jar 为主。为了应对这个问题,官方提供了插件方案,可以将第三方 jar 包进行封装为 aar 包后,再集成到 uniapp 中使用。
一、环境安装工具
1、jdk1.8环境(略)
2、Android studio官网下载 或者 Android Studio中文社区
5、自有证书生成
二、基础工程准备
-
安装好android studio后,导入离线SDK中
UniPlugin-Hello-AS
安卓项目
导入后,等待下载相关依赖,根据提示去补全sdk。确认没有错误后即可。
这里除了 app 之外的其他几个 module ,uniplugin_module
、uniplugin_component
和 uniplugin_rrichalert
是示例,都可以删除,你也可以留着参考。
如果删除这几个 module,则需要同时删除 app/build.grade
文件中的依赖和 app/src/main/assets/dcloud_uniplugins.json
中间中的内容,如下图所示:
三、创建组件
在项目根目录右击 New > Module > Android Library
到此,Module Library 创建完成。
此时刚刚创建完成后会出现编译错误 No signature of method: build_*.android() is applicable for argument types
或者 Package Name not found in xxxxxx
,这是因为我们刚刚创建项目 AndroidManifest.xml 中没有 package 属性导致的,继续向下进行,下面会讲。
1)先编辑刚刚创建的这个组件目录中的 build.gradle
文件。在最后面找到 dependencies 节点,添加导入 libs 有关的两行配置,如下:
gradle
// 这个libs是指当前module往后退一层后app目录中的libs,那个libs中有uniapp-v8-release.aar文件
compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])
// 这个libs是指当前module中的libs目录
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
**特别注意:**因为使用不同版本的 Android Studio 创建的 Module,生成的 build.gradle
里面的内容是可能不同的,这样可能会出现你这个 module 无法正常编译构建的问题,所以这里我建议复制一份 uniplugin_module
中的 build.gradle
,再修改,下面是我的完整的 build.gradle
的内容:
gradle
apply plugin: 'com.android.library'
android {
// namespace 'com.example.myfirstlibrary'
compileSdkVersion 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
// consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// 这个libs是指当前module往后退一层后app目录中的libs,那个libs中有uniapp-v8-release.aar文件
compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])
// 这个libs是指当前module中的libs目录
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
compileOnly 'androidx.appcompat:appcompat:1.0.0'
/*
implementation 'com.google.android.material:material:1.12.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
*/
}
implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
这一行代码,使用 implementation
会将 jar 包打包到 aar 文件中。
如果使用 compileOnly
则打包后的 aar 文件中不会包含 jar 包,这种不包含 jar 包的 aar 文件在使用的时候,需要同时将 jar 包文件放在和 aar 文件同级目录的 libs 文件夹中,如下图所示:
2)编辑当前创建的 module 中的 AndroidManifest.xml,添加 package 属性,如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myfirstlibrary">
</manifest>
如未配置 package 属性,会出现编译错误
Package Name not found in xxxxxx UniPlugin-Hello-AS\myfirstlibrary\src\main\AndroidManifest.xml
3)添加第三方 jar 包和对应依赖
将第三方 jar 包拷贝到 libs 目录中,如果该 jar 包需要依赖其他 jar 包,你可以选择将相关依赖的 jar 包都拷贝到 libs中,或者在 build.grade 的 dependencies 中添加依赖,最后点击右上角的 Sync Now
刷新依赖。
本例导入一个第三方的 jar包来演示对字符串进行处理测试,导入 jar 包后的截图如下:
4)在 src > main > java
的包中,新建测试的 Java类,继承io.dcloud.feature.uniapp.common.UniModule
,然后在里面编写自己的业务逻辑代码。
java
package com.example.myfirstlibrary;
import net.iharder.Base64;
import java.io.IOException;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;
/**
* 继承 UniModule 并在需要被 uniapp 调用的方法上添加 @UniJSMethod 注解
* <p>
* UniJSMethod 中的 uiThread 属性决定了被标记的方法是否在主线程(UI 线程)中执行。
* uiThread = true: 当 uiThread 设置为 true 时,标记的方法将在 UI 线程中执行。UI 线程是负责处理用户界面更新的线程,因此,如果方法涉及到 UI 更新、视图操作等,应该在 UI 线程中执行。否则,在非 UI 线程中进行这些操作会导致异常。
* uiThread = false: 当 uiThread 设置为 false 时,标记的方法将在后台线程中执行。这适用于耗时操作、IO 操作或需要在后台完成的任务,不会阻塞 UI 线程。
*/
public class HelloUniappModule extends UniModule {
/**
* 测试加密字符串
*
* @param str 参数
* @param callback js回调
*/
@UniJSMethod
public void testEncodeStr(String str, UniJSCallback callback) {
if (callback != null) {
String result = Base64.encodeBytes(str.getBytes());
callback.invoke(result);
}
}
@UniJSMethod
public void decodeBase64(String encodedStr, UniJSCallback callback) throws IOException {
if (callback != null) {
byte[] decodedBytes = Base64.decode(encodedStr);
callback.invoke(new String(decodedBytes));
}
}
}
同样因为是通过反射调用,Module 不能被混淆。请在混淆文件中添加代码:
bash
-keep public class * extends io.dcloud.feature.uniapp.common.UniModule{*;}
Module 扩展的方法可以使用 int, double, float, String, Map, List ,com.alibaba.fastjson.JSONObject 类型的参数。
三、配置插件
1、文件 app/src/main/assets/dcloud_uniplugins.json
,添加内容如下:
json
{
"nativePlugins": [
{
"plugins": [
{
"type": "module",
"name": "My-First-Plugin",
"class": "com.example.myfirstlibrary.HelloUniappModule"
}
]
}
]
}
2、文件 app/build.grade
添加插件
四、打包插件
默认情况下打包是 debug 打包,生成的 aar 文件中也包含 debug 字样,我们最终使用还是希望使用 release 正式版,并且正式版本你可能做了混淆或者压缩对其等处理(具体配置可以在 build.gradle
文件的 buildTypes
块中配置。
如果希望进行 release 打包,如下图所示操作即可:
切换 buildType 后,再执行构建,生成的包就是对应类型的文件了。
最后,将这个 aar 文件拷贝出来添加到 uniapp 代码工程里使用,至于如何在 uniapp 中集成并使用 aar 文件,本文不做赘述。
官方文档:开发者须知 | uni小程序SDK
参考资料:uniapp调用Java库 | uniapp使用第三方jar
(END)