uni原生插件在android studio环境可以使用,hbuilderx环境无法使用

项目场景:

编写module插件,调用第三方SDK的arr包来实现安卓手持机打印功能。调用、检查打印机等功能由第三方SDK实现。

项目目录层级:

在rskApi模块下只有一个RskApi-release.aar包  

rskApi模块build.gradle

configurations.maybeCreate("default")
artifacts.add("default", file('RskApi-release.aar'))

rskPrinter模块build.gradle 

plugins {
    id 'com.android.library'
}
android {
    namespace 'com.softetone.rskprinter'
    compileSdkVersion 30
    defaultConfig {
        minSdkVersion 21
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {
    //必须添加的依赖
    compileOnly 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
    compileOnly 'androidx.core:core:1.1.0'
    compileOnly 'androidx.fragment:fragment:1.1.0'
    compileOnly 'androidx.appcompat:appcompat:1.1.0'
    compileOnly 'androidx.legacy:legacy-support-v4:1.0.0'
    compileOnly 'androidx.recyclerview:recyclerview:1.1.0'
    compileOnly 'com.alibaba:fastjson:1.2.83'
    compileOnly 'org.projectlombok:lombok:1.18.16'
    annotationProcessor 'org.projectlombok:lombok:1.18.16'
    compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')
    // 此处引用了rskApi模块,而rskApi模块下只有一个arr文件
    // 因此打包之后需要把rskApi模块下的arr文件和rskPrinter模块打包生成的arr文件放在前端android目录下
    // package.json引用只引用rskPrinter插件不需要引入rskApi
    implementation project(':rskApi')
    //implementation fileTree(dir: '../rskPrinter/libs', include: ['*.aar'], exclude: [])
}

rskPrinter模块下类部分代码

public class RskPrinterModule extends UniModule {
    /**
     * 初始化打印机
     */
    @UniJSMethod(uiThread = false)
    public void initPrinter(UniJSCallback callback) {
        ResultBody resultBody = new ResultBody();
        try{
            PrinterUtils.getInstance().init();
            //校验打印机状态
            resultBody= getStatus();
        }catch (Exception e){
            resultBody= ResultBody.fail().msg("打印机初始化失败:"+e.getMessage());
        }
        callback.invoke(resultBody);
    }
    @JSMethod(uiThread = true)
    public void testText(JSONObject jsonObject, JSCallback jsCallback) {
        Log.i("RskPrinter", "成功调用testText方法");
        String name = jsonObject.getString("name");
        String age = jsonObject.getString("age");
        JSONObject result = new JSONObject();
        result.put("code", "调用成功1.0.7");
        result.put("name", name);
        result.put("age", age);
        jsCallback.invoke(result);
    }
}

问题描述

        uni原生插件在android studio环境可以使用,hbuilderx环境无法使用

        在AndroidStudio上打包为arr包后放在前端项目的android目录下,前端调用时打印插件可以看到插件的initPrinter和testText方法,但是只有testText方法调用成功。

        但是在Hbuilder上将前端项目打包为App资源放在AndroidStudio下的app/src/main/assets/apps目录下运行,可以正常调用RskPrinterModule类下的initPrinter和testText方法。

        怀疑是Hbuilder打包问题,在AndroidStudio尝试打包为apk文件后在设备上安装操作,同样还是只有testText方法调用成功。


原因分析:

        在initPrinter方法中有调用rskApi包的方法,因此怀疑是否为打包rskPrinter时没有将rskApi打包进去。


解决方案:

        将rskPrinter打包的rskPrinter-release.aar和RskApi-release.aar一起放在前端的android目录下。

        在package.json中只需要引入 rskPrinter-release.aar

{
	"name": "RskPrinter-Plugin",
	"id": "RskPrinter-Plugin",
	"version": "1.3",
	"description": "调用手持机进行打印功能",
	"_dp_type":"nativeplugin",
	"_dp_nativeplugin":{
		"android": {
			"plugins": [
				{
					"type": "module",
					"name": "RskPrinter-Plugin",
					"class": "com.softetone.rskprinter.RskPrinterModule"
				}
			],
			"integrateType": "aar",
			"dependencies": [
				
			],
			"compileOptions": {
				"sourceCompatibility": "1.8",
				"targetCompatibility": "1.8"
			},
			"abis": [
				"armeabi-v7a",
				"arm64-v8a",
				"x86"
			],
			"minSdkVersion": "28",
			"permissions": []
		}
	}
}

以下为在Hbuilder论坛查找资料时所收集的同样问题的解决方案:

1.在打包的aar中,如果包含了私有maven仓库的内容,官方文档中有提到过,仅支持一些官方的仓库,可以通过下载源码,将其打包成aar,再调用;

2.和1问题类似的,还有可能是没有在dependencies节点下填写依赖库;

3.通过libs文件夹导入的aar文件,也需要对应的拷贝到uni端;

rskPrinter下的build.gradle引用rskApi配置修改

修改前:

dependencies {
    ...
    implementation project(':rskApi')
    //implementation fileTree(dir: '../rskPrinter/libs', include: ['*.aar'], exclude: [])
}

 修改后:

dependencies {
    ...
    provided files('libs/RskApi-release.aar')
    //implementation fileTree(dir: '../rskPrinter/libs', include: ['*.aar'], exclude: [])
}

4.如果引用的第三方SDK为jar包,需要放在前端android的libs目录下

如果arr包中的方法有引入第三方 Jar 包的方法,则不需要这么操作,Gradle 会自动处理依赖关系并确保插件中的 Jar 包能够正确地被引用。 

只有在插件的 android/libs 目录中包含了其他与原生插件模块无关的 Jar 包时,才需要将原生插件模块模块中的 Jar 包复制到插件的 android/libs 目录下。

参考资料:

开发者须知 | uni小程序SDK

uniapp 调用安卓原生插件 安卓原生又调用了第三方sdk,安卓生成aar报后,uniapp调用arr包时,第三方sdk调用无效 - DCloud问答