在uniapp开发过程中有很多限制,例如下载文件时无法自定义请求头、消息推送开启cover模式时无法同时显示多个需要实时更新的消息,这里可以选择自己写一个本地插件来依靠Java完成这些功能;
第一步:在uniapp项目的根目录创建nativeplugins文件夹,文件夹下可以创建多个文件夹,最好以要创建的插件名来命名它们。
第二步:在nativeplugins文件夹中的子文件夹中创建package.json以及android文件夹,这里的android文件夹最终是用来放aar文件的。
第三步:在项目外部新建一个纯英文的文件夹(包含中文和特殊字符可能会在打包的时候报错),文件夹中新建library文件夹以及build.gradle、gradle.properties、settings.gradle这三个文件,进入library文件夹后再次创建一个build.gradle文件(作用不同必须要创建),以及src\main\java\io\dcloud\uni\插件名文件夹\Java文件 这样格式的目录,在main文件夹中创建AndroidManifest.xml文件;
第四步:开始逐个编辑创建的文件内容;
settings.gradle文件中:
rootProject.name = "你的插件名称"//即你uni文件夹下创建的文件夹名称
include ":library"
在gradle.properties文件夹中存放的一般是配置参数,可以存一些常量。
//gradle.properties
android.useAndroidX=true
android.enableJetifier=true
与library文件同级的build.gradle文件一般是固定的内容
//顶层build.gradle文件
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
而library文件夹下的build.gradle用来配置整个工程的构建环境,可以统一配置各模块都要用到的仓库源、提供构建环境和公共配置等作用。
//build.gradle
plugins {
id 'com.android.library' //这里是固定的,除非不用library模式
}
android {
namespace 'io.dcloud.uni.插件名' //这个就是底层Java文件的包名
compileSdkVersion 33
defaultConfig {
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0.0"
}
buildTypes {
release {
consumerProguardFiles 'consumer-rules.pro'
}
}
}
dependencies {
implementation 'androidx.core:core:1.10.1'
implementation "androidx.localbroadcastmanager:localbroadcastmanager:1.0.0"
}
AndroidManifest.xml文件中最低限度只需要写
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Java文件的包名">
//这里可以使用<uses-permission android:name="android.permission.xxx"/>来申请你需要的权限,但一般都是在uniapp中申请
</manifest>
最后在你的Java文件中编译你需要的内容就可以了,这里和正常Java不一样的是没有入口函数,所有的调用都是在uniapp中;
第五步:回到插件文件的根目录中,在地址栏输入cmd进入,使用gradle assembleRelease进行打包成aar文件,这里的gradle需要你提前去下载并配置好环境变量,没有配置的可以去搜一下;
正常打包完成后,会生成很多文件夹,在library\build\outputs\aar中就可以找到你的目标文件,将这个文件复制进你uniapp项目中的nativeplugins下目标插件文件夹内的android文件夹中即可;
第六步:配置uniapp项目中android文件夹的同级package.json文件
{
"name": "Java文件包名的最后那一段",
"id": "同上",
"version": "1.0.0",
"description": "manifest.json中看到的模块名",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"plugins": [{
"type": "module",
"name": "Java文件包名的最后那一段",
"class": "io.dcloud.uni.downloadFile.Java类名"
}],
"libs": ["你打包出来的aar文件名],
"integrateType": "aar",
"minSdkVersion": "21",
"abis": ["armeabi-v7a", "arm64-v8a"],
"permissions": [
//这里是你需要申请的权限
]
}
}
}
这里配置好后就可以在manifest.json的原生插件配置中选择到配置好的本地插件了。
第七步:在uniapp中使用Java文件中的函数;
在确认好以及勾选完目标插件后,在线上调试需要用到自定义基座,在hbuilder中选择运行--->运行到手机或模拟器------>制定自定义调试基座,在打包完成后会生成一个apk文件。
启动一个安卓版本8+的模拟器,选择这个
在打开的弹窗中选择
这样调试的时候才可以让本地插件正常运行;
接下来讲uniapp中怎么调用Java内的函数,在uniapp中使用
const a = plus.android.importClass('你Java插件的包名')
不确定是否成功可以先输出一下看是不是null,为null或undefined的话证明没有正确导入Java类;
const context = plus.android.runtimeMainActivity();\\这个作用是后续传递给Java的上下文,是必须的
这两步完成后就可以通过new来构建Java类了
const javafunction = new Java类名(context);
后续就可以通过和Java一样的调用方式javafunction.函数名来调用你的函数。
以上就是简单的Java插件在uniapp中调用,接下来是稍微复杂一点的,比如说带callback的Java函数
比如你在Java中创建了一个interface类
public interface Callback {
void onProgress();
void onSuccess();
void onError();
void onComplete();
}
public void uniappUseFunction(final Callback callback){
}
这时候uniapp中直接传递一个回调函数的话就会出现问题,原因可能是Java认为你并没有实现接口中的函数,所以在uniapp中需要做一点改动
const callback = plus.android.implements(
'io.dcloud.uni.Java文件夹名.Java类名$interface类名', {
onProgress: function() {
},
onSuccess: function() {
},
onError: function(){
},
onComplete() {
}
}
);
将这个callback传递给Java函数并接收信息。
在uniapp端调用Java函数的时候有可能会出现问题,但打包成aar的Java并不支持使用System.out.println来输出你想看到的信息,所以这里提供一个另类的方法供调用Java插件时排查错误使用.
private StringBuilder debugLog = new StringBuilder();
private void log(String msg) {
debugLog.append(msg).append("\n");
}
public String getJavaLog() {
return debugLog.toString();
}
在你调用的Java函数中使用log添加你想要查看或排查的信息,最终在uniapp端使用getJavaLog,最好是先调用完逻辑后加个settimeout保证信息完整。
463

被折叠的 条评论
为什么被折叠?



