背景:昨天公司的合作伙伴来了几个技术人员,他们遇到问题。在uniapp中引用自己开发的插件,插件中包含了硬件设备厂商给的安卓sdk,sdk中包含了so库,结果App中调用失败。至于报错的原因他们也没告诉我(估计也不懂拿源码真机调试看logcat);我给了他们几个节点去一一排查:1、so库有没有被打包进去;2、logcat具体抛什么异常;3、混淆;
他们也有问别的安卓开发人员,说是uniapp本身就不支持so库;心想,怎么说也是个跨平台框架、况且人家也支持插件开发,怎么可能是框架本身的问题。那就亲自动手试试,之前没接触过,正好学习学习。
先看教程咯。官方文档;PS:SDK在百度网盘,那个下载速度,没会员的可以提前下载,资源已上传可以直接下载SDK下载;
工具准备起来:HBuilder X,Android studio 4.x;
同时要准备一个HBuilder账号;登录控制台(配置appid等等信息)
一、运行官方demo
先把UniPlugin-Hello-AS工程引入到AndroidStudio中。
跑起来,诶,你会发现,需要配置AppKey,appid;
HBuilder,账号登录,导入UniPlugin-Hello-AS下的uniapp示例工程源码。然后如下图操作
打包资源,有点费时间
然后登录HBuilder控制台,找到刚刚获取的应用
填写包名,证书SHA1(证书生成就不讲了),这个时候就有appid和Appkey了;
回到Androidstudio,打开app-AndroidManifest.xml,最底下
<meta-data android:name="dcloud_appkey" android:value="替换成APPKEY" />
导出App资源
找到刚刚HBuilder导出的资源包,复制到app-src-main-assets-apps,注意是以appid文件夹文件夹名称,全部复制。原先的文件夹就删掉了。检查www路径下的manifest.jsonappid是否是刚才申请的;至此,就可以运行了。
二、写插件
demo带了3个插件可以点击体验,看看源码、模仿写一个,毕竟自己动手比较有趣。那就以zbra(二维码解析)作为插件的功能;废话不多说,动手搬砖;
以这个版本作为基础,把源码下载下来,为了避免多重引用库,直接挪代码到插件中集成,避开点坑。
新建uniplugin-zebra module
切换到Androidstudio在UniPlugin-Hello-AS工程下,新建module-library(uniplugin-zebra);
build.gradle配置如下
apply plugin: 'com.android.library'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
ndk {
abiFilters 'armeabi','armeabi-v7a','arm64-v8a','mips','mips64','x86_64','x86'
}//zbra支持的abi架构
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
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 {
//jar包
implementation fileTree(dir: 'libs', include: ['*.jar'])
compileOnly fileTree(dir: '../app/libs', include: ['uniapp-v8-release.aar'])
// implementation 'me.dm7.barcodescanner:zbar:1.5'
compileOnly 'com.alibaba:fastjson:1.1.46.android'
compileOnly "com.android.support:recyclerview-v7:28.0.0"
compileOnly "com.android.support:support-v4:28.0.0"
compileOnly "com.android.support:appcompat-v7:28.0.0"
}
引用zbar
接着把barcodescaner项目的资源挪到插件中;
把上图三个module的资源复制到插件module下,结果如下图
整理好res,配置好AndroidManifest.xml;
me.dm7.barcodescanner.zbar.sample包含了demo的扫描二维码activity;等会直接跳转过来使用。
编译没问题;
开始写插件。
新建TestModule.java继承UniModule,不要问为什么,模仿的;
这边是跳转NativePageActivity,改成我们要的SimpleScannerActivity;
至此,搬砖完成一半。
打包,配置插件
打包出aar,在HBuilderX配置插件。也可在gradle生成;
切到HBuilderX,在工程下新建文件夹nativeplugins并创建插件文件夹uniplugin_zebra-debug;
重点配置文件package.json,还有安卓和ios插件包,这里没iOS跳过,在uniplugin_zebra-debug下创建android文件夹,把刚刚的aar文件放进去。结构如下。
这边package.json内容:具体编写规则可言看文档package.json规范
{
"name": "uniplugin_zebra",
"id": "uniplugin_zebra-debug",
"version": "1.0.0",
"description": "zebra",
"_dp_type":"nativeplugin",
"_dp_nativeplugin":{
"android": {
"plugins": [
{
"type": "module",
"name": "ZebraModule" ,
"class": "com.janbo.zebra.TestModule"
}
],
"hooksClass": "",
"integrateType": "aar",
"dependencies": [
],
"compileOptions": { //可选,Java编译参数配置
"sourceCompatibility": "1.8",
"targetCompatibility": "1.8"
},
"abis": [//"可选, 支持的abi类型, 可取值armeabi-v7a|arm64-v8a|x86",这边就全干上不管了
"armeabi|armeabi-v7a|arm64-v8a|mips|mips64|x86_64|x86"
],
"minSdkVersion": "16",
"useAndroidX": false, //可选,是否兼容使用AndroidX
"permissions": [
"android.permission.CAMERA"
],
"parameters": {
}
}
}
}
然后在manifest.json选择本地原生插件
调用插件;
打开pages/sample/ext-module.nvue;
引入插件:var zebraModule = uni.requireNativePlugin("ZebraModule")
调用方法:zebraModule.gotoNativePage();
完成,如上打包App资源,到AS中替换,运行,不出什么意外的话,点击按钮会闪退,报错,要嘛加载不到so库,要嘛no "J" field "peer" in class "Lnet/sourceforge/zbar/ImageScanner;" or its superclasses;
at net.sourceforge.zbar.ImageScanner.init(Native Method)
;没关系就是来解决问题的,
解决问题
1、so加载不到,要嘛没打包进去,要嘛没有对应的库。细心的同学可能就发现了,package.json规范中有提到
也就是插件中的jar,so都得丢进来咯;
2、o "J" field "peer" in class "Lnet/sourceforge/zbar/ImageScanner;"很明显就是混淆引起的,插件module没有配置混淆,那就是基座app有配置,果不其然
minifyEnabled true改为minifyEnabled false;
统统重新打包。诶,怎么还没有扫描框,噢安卓6.0得动态获取相机权限,免去麻烦,进入手机设置允许权限,就可以愉快扫码啦;
至此,uniapp插件开发学习;有不足、欢迎指正;