<原創(chuàng)聲明>本文首發(fā)于微信公眾號,具有原創(chuàng)標識,秉著知識共享、互幫互助的原則歡迎大家的轉載,但轉載須有度,還請加出處,請尊重別人的勞動成果,謝謝。
uni-app是啥,套用官方的話,它是一個使用?Vue.js?開發(fā)所有前端應用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘/淘寶)、快應用等多個平臺。
當你使用uni-app來對項目進行開發(fā)時,免不了使用各種各樣的插件,官方的插件市場(https://ext.dcloud.net.cn)雖有上千款,但是一個項目如果是高度自定義的話,那難免對插件的功能有著特定的需求,這時就需要自己開發(fā)原生插件來滿足需要了。
官方早早注意到了這點,對原生插件開發(fā)的定義也很貼合實際:當HBuilderX中提供的能力無法滿足App功能需求,需要通過使用Andorid/iOS原生開發(fā)實現(xiàn)時,可使用App離線SDK開發(fā)原生插件來擴展原生能力。
但是不可否認的是,官方給出的文檔還是過于跳脫簡潔。對老手而言,上手似乎沒有什么難度,對新手就不怎么友好了。
所以重點就來了,本次演示uni原生插件安卓開發(fā)流程,以Module擴展為例,絕對是從頭到尾的“一條龍服務”,當然為了更好的理解開發(fā)思路,文章還是依照官方文檔來的。
下面步入正題。
第一步,開發(fā)環(huán)境的準備
JAVA環(huán)境配置:
以windows10為例,cmd進入自己電腦命令提示符,輸入java -version查看自己的jdk版本,官方文檔中提示jdk版本應在1.7及以上,最優(yōu)1.8,如果達不到標準,自行下載相關版本配置好環(huán)境變量即可。
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原生插件開發(fā)教程(android)網址:
https://nativesupport.dcloud.net.cn/NativePlugin/course/android
第二步,創(chuàng)建自定義項目與引入官方項目
打開AndroidStudio,在菜單欄選擇File>New>New Project,創(chuàng)建自定義項目。
因為第一步代表AndroidStudio已經測試完成,能夠正常使用,所以我們直接創(chuàng)建No Activity項目,點擊Next。
填寫項目名、包名,以及Minimum API Level(有疑惑可參照《HBuilderX安卓離線打包》圖文第一步)
項目創(chuàng)建完畢,為了更好的使用,我們把它轉到Project視圖。
接下來創(chuàng)建要開發(fā)的模塊,本文在Module和Component 擴展中選擇Module擴展為例。
點擊File>New>New Module...
選擇Android Library,點擊Next
自定義Library名和包名(這里是com.test.testplugin)點擊Finish
創(chuàng)建完畢后如圖所示
接下來導入官方提供的uni插件原生項目,里面的東西我們待會兒要用到
File>New>Import Project...
項目在官方的離線SDK中,我是直接把它拷到AndroidStudio默認存放路徑了,這樣方便導入。
如圖,點擊OK
導入成功,我們參照里面的uniplugin_module模塊
配置剛剛創(chuàng)建的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'
再添加后續(xù)用到的json解析庫
compileOnly 'com.alibaba:fastjson:1.1.46.android'
接下來導入uniapp-release.aar插件,它是擴展module主要依賴庫(此時也可以把離線打包用到的另外三個插件一起導入)
在app>libs目錄下導入插件,如圖
回到剛剛創(chuàng)建的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
第三步,原生插件的開發(fā)
以擴展Module為例,參照官方UniPlugin-Hello-AS工程中的uniplugin_module模塊,如圖創(chuàng)建類TestModule
TestModule需要繼承WXModule類
Module擴展注意事項:
weex擴展API for android:
http://weex.apache.org/cn/guide/extend-android.html
下面簡單舉個例子:
如圖創(chuàng)建testText()方法,通過options.getString(XX)獲取vue或nvue頁面?zhèn)魉偷讲寮膎ame和age信息。
name和age為空則反饋輸入無效信息,不為空判斷age,age小于0和大于30不合格,在合格范圍(0~30)內,年齡大于0且小于10時返回信息自動補0。
接下來在本地注冊插件
在app>src>main目錄下創(chuàng)建assets文件夾
在app>src>main>assets目錄下創(chuàng)建dcloud_uniplugins.json文件,我們也可以拷貝剛剛導入官方的項目中的json文件,對其稍作修改。
對dcloud_uniplugins.json中的內容做出適當修改
參照相關說明
(注冊方法一)
因為當前只舉了Module擴展的一個例子,所以要刪除掉多余元素,完成后如圖
(注冊方法二)
對創(chuàng)建的Module擴展testplugin進行操作,在 src>main>java>插件包名(這里是com.test.testplugin)目錄下創(chuàng)建類TestModule_AppProxy
TestModule_AppProxy類要實現(xiàn)AppHookProxy接口,在onCreate()方法中添加weex注冊相關參數(shù)或填寫插件需要在啟動時初始化的邏輯。
在hooksClass節(jié)點填入你創(chuàng)建的實現(xiàn)AppHookProxy接口的實體類的完整名稱 (注:有些需要初始化操作的需求可以在此處添加邏輯,無特殊操作僅使用第一種方式注冊即可無需集成AppHookProxy接口)
注冊完畢,開始打包插件
在Gradle>testplugin>Tasks>other目錄下找到assembleRelease,雙擊等待系統(tǒng)編譯出擴展module的aar文件
注意:官方文檔中是選擇Gradle--->插件module--->Tasks--->build--->assembleRelease編譯module的aar文件,在新版本的AndroidStudio中,assembleRelease和assembleDebug被轉移到other目錄下。
成功后在testplugin>build>outputs>aar目錄下就可以找到相關插件了
第四步,HBuilderX導入和使用本地插件
如圖,創(chuàng)建uni-app默認項目TestModule
參照官方文檔中的目錄規(guī)范,將剛才打包的插件放到nativeplugins>插件文件夾名稱(我的是Test-Module)>android目錄下,沒有相關目錄就一步步創(chuàng)建。
創(chuàng)建package.json——uni原生插件描述文件,放到插件文件夾名稱目錄下,與android文件夾并列
package.json官方描述文檔:
https://nativesupport.dcloud.net.cn/NativePlugin/course/package
按照要求填寫相關信息
注意:插件標識id必須在對應android和ios節(jié)點下plugins中進行注冊,與name字段值一致。name下的class是注冊插件的類名,也要填對。
這里因為只有android插件,就把ios節(jié)點全部刪掉,在這里直接注釋的話是無效的。
還有要注意的一點:插件標識id一定要與插件文件夾名稱一致,不然在云打包時會提示插件不合法:該插件在nativePlugins目錄下不存在。
在manifest.json下配置App原生插件
勾選并確認
parameters信息根據需求配置
接下來在HBuilderX內對項目中的index.vue文件(在pages>index目錄下)做出一定更改,以便后續(xù)測試開發(fā)的原生插件。
如圖,利用
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云端打包信息
在這里使用了自有證書,這是之前圖文中創(chuàng)建的,密碼123456
下面選中了打自定義調試基座(iOS的safari調試需要用蘋果開發(fā)證書打包),因為是要測試,所以不要點到打正式包上了
云端打包
提交到云端服務器
打包完成
打包成功后需要在下圖位置確保開啟自定義調試基座功能:
可以在項目unpackage下看到打包后的測試apk文件
啟動模擬器,運行
模擬器啟動成功
進入測試項目
輸入姓名tom和年齡9(大于0小于10前面自動補0)測試插件,點擊提交
反饋提交結果
把年齡改為31(插件設置年齡范圍為0~30),反饋如下
測試成功
附加
如果Module擴展模塊做出了更改,順著Gradle>testplugin>Tasks>other目錄
選擇assembleDebug或者assembleRelease雙擊等待系統(tǒng)編譯成aar文件
編譯完成后,在testplugin>build>outputs>aar中找到相關文件,復制粘貼到相關目錄下,替換之前的插件
再進行云打包基座調試即可
因為通過離線打包制作自定義基座來運行和通過AndroidStudio來運行條件基本一致,所以前期先把共同條件配置好(與離線打包高度相似)
配置運行條件
①配置AndroidManifest.xml
在app>src>main下配置AndroidManifest.xml文件
將其修改為
然后繼續(xù)下一步,添加內容到application節(jié)點(建議復制官方文檔里的,下面的復制粘貼后排版會比較亂)。
<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文件夾,打開可以發(fā)現(xiàn)下圖幾個文件。
可以發(fā)現(xiàn),較上一版本2.6.16少了dcloud1.dat和dcloud2.dat兩個文件
官方文檔中給出了說明:dcloud1.dat、dcloud2.dat為uni-app所需資源,2.7.0之后已不再需要,升級時需要刪除,可以減少apk大小。
返回上一級,復制data文件夾如上一步操作,為了方便與四個文件放到一起。
如圖,在發(fā)行(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為創(chuàng)建時的包名,minSdkVersion為兼容最小的版本號,targetSdkVersion為目標版本,有興趣的可以百度一下三者之間的區(qū)別和聯(lián)系。
注意,官方文檔中標注“App離線SDK minSdkVersion最低支持19,小于19在部分4.4以下機型上將無法正常使用?!?/p>
versionCode需要設定一個數(shù)值,一般初始為1,更新版本時versionCode的值需要做出更改,每次都要比前一個設置的值大,否則無法正常安裝。
versionName一般填寫主版本號次版本號和修正號,如圖中的“1.0.0”為最初版本號,其余的可以自行查閱。
然后同步處理
同步完成
把剛剛轉移到自定義文件夾下的data文件夾拷貝到app>src>main>assets目錄文件夾下。
繼續(xù)在剛剛創(chuàng)建的assets文件夾下創(chuàng)建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一致(不一致會出現(xiàn)白屏等狀況)。
并設置根節(jié)點的debug和syncDebug為true
條件配置完畢
名稱配置
在app>src>main>res>values配置strings.xml文件,打開xml文件,與剛剛引入本地打包資源的里的manifest.json文件比較,發(fā)現(xiàn)名字不一致,遂把strings.xml里的name改為“TestModule”。
(注:manifest.json文件在
assets>apps>__UNI__179390F>www目錄下)
通過離線打包制作自定義基座來運行
開始打debug包,方法Ⅰ
如圖,在Gradle>app>Tasks>other目錄下找到assembleDebug或者assembleRelease,雙擊等待系統(tǒng)編譯完成
編譯完成后,在app>build>outputs>apk文件夾下即可找到debug和release相關apk文件
開始打debug包,方法Ⅱ
如圖,在菜單欄Build?>?Build Bundle(s)/APK (s)下選擇Build APK(s),等待系統(tǒng)編譯
編譯完成,在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'運行
項目成功打開,測試結果如下:
到了這一步已經可以正常打包進行實機測試了
打包流程
用到了之前圖文中創(chuàng)建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兩個例子,我怕放一起看著會亂,就先一個一個來咯。如果時間充足的話,視頻演示會在后續(xù)放出。
最后