uni原生插件Android开发流程一览—Module扩展

<原创声明>本文首发于微信公众号,具有原创标识,秉着知识共享、互帮互助的原则欢迎大家的转载,但转载须有度,还请加出处请尊重别人的劳动成果,谢谢。


uni-app是啥,套用官方的话,它是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。

当你使用uni-app来对项目进行开发时,免不了使用各种各样的插件,官方的插件市场(https://ext.dcloud.net.cn)虽有上千款,但是一个项目如果是高度自定义的话,那难免对插件的功能有着特定的需求,这时就需要自己开发原生插件来满足需要了。

官方早早注意到了这点,对原生插件开发的定义也很贴合实际:当HBuilderX中提供的能力无法满足App功能需求,需要通过使用Andorid/iOS原生开发实现时,可使用App离线SDK开发原生插件来扩展原生能力。

但是不可否认的是,官方给出的文档还是过于跳脱简洁。对老手而言,上手似乎没有什么难度,对新手就不怎么友好了。

所以重点就来了,本次演示uni原生插件安卓开发流程,以Module扩展为例,绝对是从头到尾的“一条龙服务”,当然为了更好的理解开发思路,文章还是依照官方文档来的。

下面步入正题。

第一步,开发环境的准备

JAVA环境配置:

以windows10为例,cmd进入自己电脑命令提示符,输入java -version查看自己的jdk版本,官方文档中提示jdk版本应在1.7及以上,最优1.8,如果达不到标准,自行下载相关版本配置好环境变量即可。

jdk下载路径:

https://www.oracle.com

https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

AndroidStudio配置:

验证AndroidStudio是否配置成功,具体流程可参照《HBuildeX安卓离线打包教程》相关图文第一步。若测试项目能够显示“Hello World!”并且无报错,代表项目成功跑起,AndroidStudio基本配置完成。

AndroidStudio下载路径:

https://developer.android.google.cn/studio/index.html

http://www.android-studio.org/

App离线SDK下载:

在DCloud官网下载好安卓离线SDK,解压以待使用。

Android离线SDK下载路径:

https://nativesupport.dcloud.net.cn/AppDocs/download/android

官方uni原生插件开发教程(android)网址:

https://nativesupport.dcloud.net.cn/NativePlugin/course/android

第二步,创建自定义项目与引入官方项目

打开AndroidStudio,在菜单栏选择File>New>New Project,创建自定义项目。

因为第一步代表AndroidStudio已经测试完成,能够正常使用,所以我们直接创建No Activity项目,点击Next

填写项目名、包名,以及Minimum API Level(有疑惑可参照《HBuilderX安卓离线打包》图文第一步)

项目创建完毕,为了更好的使用,我们把它转到Project视图。

接下来创建要开发的模块,本文在Module和Component 扩展中选择Module扩展为例。

点击File>New>New Module...

选择Android Library,点击Next

自定义Library名和包名(这里是com.test.testplugin)点击Finish

创建完毕后如图所示

接下来导入官方提供的uni插件原生项目,里面的东西我们待会儿要用到

File>New>Import Project...

项目在官方的离线SDK中,我是直接把它拷到AndroidStudio默认存放路径了,这样方便导入。

如图,点击OK

导入成功,我们参照里面的uniplugin_module模块

配置刚刚创建的testplugin的build.gradle(testplugin)信息

如图,将dependencies下默认生成的依赖注释掉,添加uni-app所需库依赖

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'

再添加后续用到的json解析库

compileOnly 'com.alibaba:fastjson:1.1.46.android'

接下来导入uniapp-release.aar插件,它是扩展module主要依赖库(此时也可以把离线打包用到的另外三个插件一起导入)

app>libs目录下导入插件,如图

回到刚刚创建的testplugin的build.gradle(testplugin)中,接下来进行导入aar需要的配置操作

添加

repositories {    

    flatDir { 

            dirs 'libs'   

     } 

}

到dependencies{}上方,注意,不要把它放到android{}里了

在dependencies内添加

compileOnly fileTree(dir: '../app/libs', include: ['uniapp-release.aar'])

上述配置全览

点击Sync Now或者Sync Project with Gradle Files进行同步处理(同步失败或过慢请参照uni-app离线打包图文)

官方文档提醒:

工程gradle配置的为gradle-4.6-all版本,使用的是新版本的依赖方式。如果您使用的是老版本的gradle,可根据以下链接进行修改依赖方式。

https://blog.csdn.net/wangliblog/article/details/81366095

第三步,原生插件的开发

以扩展Module为例,参照官方UniPlugin-Hello-AS工程中的uniplugin_module模块,如图创建类TestModule

TestModule需要继承WXModule

Module扩展注意事项:

weex扩展API for android:

http://weex.apache.org/cn/guide/extend-android.html

下面简单举个例子:

如图创建testText()方法,通过options.getString(XX)获取vue或nvue页面传送到插件的name和age信息。

name和age为空则反馈输入无效信息,不为空判断age,age小于0和大于30不合格,在合格范围(0~30)内,年龄大于0且小于10时返回信息自动补0。

接下来在本地注册插件

在app>src>main目录下创建assets文件夹

在app>src>main>assets目录下创建dcloud_uniplugins.json文件,我们也可以拷贝刚刚导入官方的项目中的json文件,对其稍作修改。

对dcloud_uniplugins.json中的内容做出适当修改

参照相关说明

(注册方法一)

因为当前只举了Module扩展的一个例子,所以要删除掉多余元素,完成后如图

(注册方法二)

对创建的Module扩展testplugin进行操作,在 src>main>java>插件包名(这里是com.test.testplugin)目录下创建类TestModule_AppProxy

TestModule_AppProxy类要实现AppHookProxy接口,在onCreate()方法中添加weex注册相关参数或填写插件需要在启动时初始化的逻辑。

hooksClass节点填入你创建的实现AppHookProxy接口的实体类的完整名称 (注:有些需要初始化操作的需求可以在此处添加逻辑,无特殊操作仅使用第一种方式注册即可无需集成AppHookProxy接口)

注册完毕,开始打包插件

Gradle>testplugin>Tasks>other目录下找到assembleRelease,双击等待系统编译出扩展module的aar文件

注意:官方文档中是选择Gradle--->插件module--->Tasks--->build--->assembleRelease编译module的aar文件,在新版本的AndroidStudio中,assembleReleaseassembleDebug被转移到other目录下。

成功后在testplugin>build>outputs>aar目录下就可以找到相关插件了

第四步,HBuilderX导入和使用本地插件

如图,创建uni-app默认项目TestModule

参照官方文档中的目录规范,将刚才打包的插件放到nativeplugins>插件文件夹名称(我的是Test-Module)>android目录下,没有相关目录就一步步创建。

创建package.json——uni原生插件描述文件,放到插件文件夹名称目录下,与android文件夹并列

package.json官方描述文档:

https://nativesupport.dcloud.net.cn/NativePlugin/course/package

按照要求填写相关信息

注意:插件标识id必须在对应android和ios节点下plugins中进行注册,与name字段值一致。name下的class是注册插件的类名,也要填对。

这里因为只有android插件,就把ios节点全部删掉,在这里直接注释的话是无效的。

还有要注意的一点:插件标识id一定要与插件文件夹名称一致,不然在云打包时会提示插件不合法:该插件在nativePlugins目录下不存在

在manifest.json下配置App原生插件

勾选确认

parameters信息根据需求配置

接下来在HBuilderX内对项目中的index.vue文件(在pages>index目录下)做出一定更改,以便后续测试开发的原生插件。

如图,利用

const XXX= uni.requireNativePlugin('XXX-XXX');

形式在vue或者nvue中引入本地插件,“XXX-XXX”为package.json中的id。

解释修改后的index.vue:

代码中有两个输入框,分别输入name和age,点击提交按钮,调用methods中的testText()方法,将输入的name和age的值传到插件进行处理。

第五步,运行项目的三种方式

通过在线打包制作自定义基座来运行

在HBuilderX里选定项目

运行(R)>运行到手机或模拟器(N)>制作自定义调试基座(P)

配置App云端打包信息

在这里使用了自有证书,这是之前图文中创建的,密码123456

下面选中了打自定义调试基座(iOS的safari调试需要用苹果开发证书打包),因为是要测试,所以不要点到打正式包上了

云端打包

提交到云端服务器

打包完成

打包成功后需要在下图位置确保开启自定义调试基座功能:

可以在项目unpackage下看到打包后的测试apk文件

启动模拟器,运行

模拟器启动成功

进入测试项目

输入姓名tom和年龄9(大于0小于10前面自动补0)测试插件,点击提交

反馈提交结果

把年龄改为31(插件设置年龄范围为0~30),反馈如下

测试成功

附加

如果Module扩展模块做出了更改,顺着Gradle>testplugin>Tasks>other目录

选择assembleDebug或者assembleRelease双击等待系统编译成aar文件

编译完成后,在testplugin>build>outputs>aar中找到相关文件,复制粘贴到相关目录下,替换之前的插件

再进行云打包基座调试即可

因为通过离线打包制作自定义基座来运行通过AndroidStudio来运行条件基本一致,所以前期先把共同条件配置好(与离线打包高度相似)

配置运行条件

①配置AndroidManifest.xml

app>src>main下配置AndroidManifest.xml文件

将其修改为

然后继续下一步,添加内容到application节点(建议复制官方文档里的,下面的复制粘贴后排版会比较乱)。

<activity      

android:name="io.dcloud.PandoraEntry"      android:configChanges="orientation|keyboardHidden|keyboard|navigation"      

android:label="@string/app_name"      

android:launchMode="singleTask"      

android:hardwareAccelerated="true"      

android:theme="@style/TranslucentTheme"      

android:screenOrientation="user"      android:windowSoftInputMode="adjustResize" >      

<intent-filter>          

<action android:name="android.intent.action.MAIN" />          

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>  

</activity>  

<activity      

android:name="io.dcloud.PandoraEntryActivity"      

android:launchMode="singleTask"      

android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale|keyboard"      

android:hardwareAccelerated="true"      

android:permission="com.miui.securitycenter.permission.AppPermissionsEditor"      

android:screenOrientation="user"      

android:theme="@style/DCloudTheme"      

android:windowSoftInputMode="adjustResize">      

<intent-filter>          

<category android:name="android.intent.category.DEFAULT" />      

<category android:name="android.intent.category.BROWSABLE" />

<action android:name="android.intent.action.VIEW" />         

<data android:scheme="h56131bcf" />       

</intent-filter>  

</activity>

添加完成后如下图

AndroidManifest.xml配置完毕

②引入打包资源

进入下载好后的安卓离线SDK文件夹,在目录

2.7.5\Android-SDK@2.7.5.80183_20200519\SDK\libs

下找到

lib.5plus.base-release.aar

android-gif-drawable-release@1.2.17.aar

miit_mdid_1.0.10.aar

uniapp-release.aar

四个文件,复制到自定义的新文件夹方便使用

在目录

2.7.5\Android-SDK@2.7.5.80183_20200519\SDK\assets

下找到data文件夹,打开可以发现下图几个文件。

可以发现,较上一版本2.6.16少了dcloud1.dat和dcloud2.dat两个文件

官方文档中给出了说明:dcloud1.dat、dcloud2.dat为uni-app所需资源,2.7.0之后已不再需要,升级时需要删除,可以减少apk大小。

返回上一级,复制data文件夹如上一步操作,为了方便与四个文件放到一起。

如图,在发行(P)选项>原生APP-本地打包(L)中选择生成本地打包App资源(R)

显示导出成功,顺着路径将自己项目id名的文件夹拷贝,放到上一步自定义的文件夹下,方便使用。

这里我的项目id是__UNI__179390F,就把它放到如图位置

打开AndroidStudio,如下图将

lib.5plus.base-release.aar

android-gif-drawable-release@1.2.17.aar

miit_mdid_1.0.10.aar

三个文件复制粘贴到libs目录下

(第二步添加依赖时已经导入uniapp-release.aar了)

如下图在build.gradle(app)中添加引用资源

implementation fileTree(dir: 'libs', include: ['*.aar'])

implementation "com.android.support:support-v4:28.0.0"

implementation "com.android.support:appcompat-v7:28.0.0"

implementation 'com.android.support:recyclerview-v7:28.0.0'

implementation 'com.facebook.fresco:fresco:1.13.0'

implementation "com.facebook.fresco:animated-gif:1.13.0"

implementation 'com.github.bumptech.glide:glide:4.9.0'

implementation 'com.alibaba:fastjson:1.1.46.android'

自带的依赖进行注释

添加

接下来在

android{

...

        }

内添加

aaptOptions {

additionalParameters '--auto-add-overlay'  

ignoreAssetsPattern "!.svn:!.git:.*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~" 

 }

再回到build.gradle(app)页面最上边,配置app版本号。

compileSdkVersion为编译版本,buildToolsVersion为构建工具版本,applicationId为创建时的包名,minSdkVersion为兼容最小的版本号,targetSdkVersion为目标版本,有兴趣的可以百度一下三者之间的区别和联系。

注意,官方文档中标注“App离线SDK minSdkVersion最低支持19,小于19在部分4.4以下机型上将无法正常使用。”

versionCode需要设定一个数值,一般初始为1,更新版本时versionCode的值需要做出更改,每次都要比前一个设置的值大,否则无法正常安装。

versionName一般填写主版本号次版本号和修正号,如图中的“1.0.0”为最初版本号,其余的可以自行查阅。

然后同步处理

同步完成

把刚刚转移到自定义文件夹下的data文件夹拷贝到app>src>main>assets目录文件夹下。

继续在刚刚创建的assets文件夹下创建apps文件夹,把刚刚进行本地打包资源处理后的文件(我的是__UNI__179390F)拷贝到apps文件夹下。

③引入本地原生插件

在build.gradle(app)下添加

implementation project(':testplugin')

用来引入本地插件

在dependencies{}上方添加

repositories {

flatDir {

dirs 'libs'

}

}

注意:跟第二步情况一样不要把它放在android{}内

同步处理

④自定义基座的配置

在app目录下,将assets下apps文件夹中的manifest.json文件和data文件夹中的dcloud_control.xml文件打开,确保manifest.json中的id和dcloud_control.xml中的appid一致(不一致会出现白屏等状况)。

并设置根节点的debugsyncDebugtrue

条件配置完毕

名称配置

app>src>main>res>values配置strings.xml文件,打开xml文件,与刚刚引入本地打包资源的里的manifest.json文件比较,发现名字不一致,遂把strings.xml里的name改为“TestModule”。

(注:manifest.json文件在

assets>apps>__UNI__179390F>www目录下)

通过离线打包制作自定义基座来运行

开始打debug包,方法Ⅰ

如图,在Gradle>app>Tasks>other目录下找到assembleDebug或者assembleRelease,双击等待系统编译完成

编译完成后,在app>build>outputs>apk文件夹下即可找到debug和release相关apk文件

开始打debug包,方法Ⅱ

如图,在菜单栏Build Build Bundle(s)/APK (s)下选择Build APK(s),等待系统编译

编译完成,在app>build>outputs>apk>debug路径下即可找到相关apk文件

如此,debug打包完成

将app-debug.apk文件复制到项目unpackage>debug目录下,如果里面存在android_debug.apk文件,就先删除掉,再将app-debug.apk文件名称改为android_debug即可(也可先更名,粘贴进去直接复制替换掉)

运行(R)>运行手机或模拟器(N)>运行相关设备,成功运行

测试结果如下图:

测试成功

通过AndroidStudio来运行

切换到模拟器选项

点击Run 'app'运行

项目成功打开,测试结果如下:

到了这一步已经可以正常打包进行实机测试了

打包流程

用到了之前图文中创建testLove.jks文件,密码都是123456

这一块不熟的可以参照我以前图文,包括在AndroidStudio内进行app图标设置

实机测试

测试成功

附:如果运行时报device support x86 but apk only supports armeabi-v7a错误,进入到build.gradle(app)中,在

android{

defaultConfig {

//要导入地方

    }

}

内导入

ndk {

abiFilters 'x86','armeabi-v7a'

}

即可

总结

本次演示项目用的是vue文件,而官方的unipluginDemo进行插件演示时是在nvue条件下进行的,在很多方面,nvue能做的其实比vue更多,但nvue在css的写法限制性较强,也有一些缺点,具体可见

https://uniapp.dcloud.io/use-weex

演示以Module扩展举例,官方的Demo里还有uniplugin_component和uniplugin_richalert两个例子,我怕放一起看着会乱,就先一个一个来咯。如果时间充足的话,视频演示会在后续放出。

最后

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345