HarmonyOS3.0嘗鮮之關(guān)鍵Js Api--ServiceAbility開發(fā)
??想了解更多關(guān)于開源的內(nèi)容,請訪問:??
HarmonyOS3.0發(fā)布之后,大家可以從api8上可以看到一個關(guān)鍵動作,就是完全拋棄了java,并且不提供對api8以下版本的兼容,完全顛覆性變化,顯然不可能再去兼容低版本了。那么做過api7之前開發(fā)的朋友都會知道,在之前的js或者ets開發(fā)中,有幾個關(guān)鍵地方是離不開java的,比如我前面一篇博客中寫道的動態(tài)權(quán)限申請,本篇將來介紹另一個關(guān)鍵技術(shù)ServiceAbility,之前的ServiceAbility是完全基于Java開發(fā),可以說和Android里面的開發(fā)模式一樣。
下面就來上手嘗試下ServiceAbility純粹js或者ets開發(fā)吧,這里稍微吐槽下官方文檔的不足吧,我已經(jīng)反饋官方整改文檔了。文檔上的一些小錯誤和不足導(dǎo)致我打通Service的所有核心技能足足耗費了十多個小時,其中最難的莫過于Service主動給FA推送數(shù)據(jù)了,做過Android的可能都知道在Android里面這個是基于java的回調(diào)機(jī)制來實現(xiàn),而這里官方文檔是沒有說這個核心技能是如何實現(xiàn)的,js的回調(diào)機(jī)制和java的回調(diào)機(jī)制還是有非常大區(qū)別的,我開始專在回調(diào)里面出不來導(dǎo)致耗費了很久時間,最后又嘗試了N中方案終于最后找到了最優(yōu)解搞定了這個核心功能。
本篇文章先主要來個Js版本的ServiceAbility開發(fā)入門吧。
場景介紹
基于Service模板的Ability(以下簡稱“Service”)主要用于后臺運行任務(wù)(如執(zhí)行音樂播放、文件下載等),但不提供用戶交互界面。Service可由其他應(yīng)用或Ability啟動,即使用戶切換到其他應(yīng)用,Service仍將在后臺繼續(xù)運行。
接口說明
表1 Service中相關(guān)生命周期功能介紹。
開發(fā)步驟
本篇先只實現(xiàn)最基本的創(chuàng)建、啟動和停止Service。
創(chuàng)建工程
首先使用最新版的DevEco Studio(992版本)開發(fā)工具創(chuàng)建一個工程,選擇最新的api8,如下圖:
創(chuàng)建工程時,需要關(guān)注的就是上圖中所描述的bundleName和package,因為后面核心api中要使用到這兩個參數(shù),對于這兩個參數(shù)含義不清楚的可以查閱我另外一篇博客《??App與Hap、Entry與feature,bundleName與packge,務(wù)必弄明白??》。
創(chuàng)建Service
工程創(chuàng)建完成之后,鼠標(biāo)選擇js目錄,然后點擊鼠標(biāo)右鍵,如下圖依次選擇來創(chuàng)建Service。
Service也是一種Ability,Ability為Service提供了以下生命周期方法,開發(fā)者可以重寫這些方法,來添加其他Ability請求與Service Ability交互時的處理方法。
創(chuàng)建Service的代碼示例如下:
export default {
onStart(want) {
console.info('ServiceAbility onStart');
},
onStop() {
console.info('ServiceAbility onStop');
},
onConnect(want) {
console.info('ServiceAbility onConnect');
return {};
},
onReconnect(want) {
console.info('ServiceAbility onReconnect');
},
onDisconnect() {
console.info('ServiceAbility onDisconnect');
},
onCommand(want, restart, startId) {
console.info('ServiceAbility onCommand');
}
};
本篇將只講解啟動和停止服務(wù),等會寫完啟動和停止服務(wù)的觸發(fā)代碼之后,我們再來看看會有哪些生命周期函數(shù)會被回調(diào)。
由于Service也是Ability,創(chuàng)建完成Service之后,它也會自動的在應(yīng)用配置文件config.json中生成相關(guān)核心配置信息,其中有個核心配置就是type為“service”,具體如下所示:
{
"module": {
"abilities": [
{
"name": ".ServiceAbility",
"type": "service",
"visible": true
}
]
}
}
啟動Service
做個極其簡單的頁面,只放置兩個文本按鈕,分別用來觸發(fā)“啟動Service”和“停止Service”,如下圖:
Ability為開發(fā)者提供了startAbility()方法來啟動另外一個Ability。因為Service也是Ability的一種,開發(fā)者同樣可以通過將Want傳遞給該方法來啟動Service。
開發(fā)者可以通過構(gòu)造包含bundleName與abilityName的Want對象來設(shè)置目標(biāo)Service信息。參數(shù)的含義如下:
- bundleName:表示應(yīng)用唯一標(biāo)識符名稱,即config.json中的bundleName。
- abilityName:表示待啟動的Ability名稱,這里使用完整Ability名稱,即package+‘.’+Ability名稱。?
啟動本地設(shè)備Service的代碼示例如下:
首先要導(dǎo)入系統(tǒng)庫。
import featureAbility from ‘@ohos.ability.featureAbility’;
然后業(yè)務(wù)邏輯代碼如下:
//啟動service按鈕綁定的點擊事件
onClickStartService(){
let promise = featureAbility.startAbility(
{
want:
{
bundleName: "com.xdw.jsdemo",
abilityName: "com.example.entry.ServiceAbility",
},
}
);
}
執(zhí)行上述代碼后,Ability將通過startAbility() 方法來啟動Service。
- ? 如果Service尚未運行,則系統(tǒng)會先調(diào)用onStart()來初始化Service,再回調(diào)Service的onCommand()方法來啟動Service。
- 如?果Service正在運行,則系統(tǒng)會直接回調(diào)Service的onCommand()方法來啟動Service。?
不支持預(yù)覽器進(jìn)行測試,下面啟動模擬器或者真機(jī)(必須api》=8)進(jìn)行測試,多次點擊“啟動Service”按鈕觀察日志輸出,日志輸出如下圖:
停止Service
Service一旦創(chuàng)建就會一直保持在后臺運行,除非必須回收內(nèi)存資源,否則系統(tǒng)不會停止或銷毀Service。開發(fā)者可以在Service中通過featureAbility.terminateSelf()停止本Service。
這里需要注意的是官方sdk目前并沒有提供在其他Ability中主動停止Service的api,因此現(xiàn)在想簡簡單單的在UI中點擊“停止service”按鈕直接調(diào)用一個api停止service是做不到的,但并不是代表就不能通過點擊按鈕來停止服務(wù),關(guān)于這個的實現(xiàn)下篇再講。這里只講通過在當(dāng)前Service中通過featureAbility.terminateSelf()停止本Service。由于不是主動通過UI操作的,什么時候去停止服務(wù)需要個觸發(fā)時機(jī),最簡單的就是在Service中添加一個定時器來做demo演示了。代碼如下:
onStart(want) {
console.info('ServiceAbility onStart');
//5秒之后停止Service
setTimeout(()=>{
console.info('delay 5秒');
featureAbility.terminateSelf();
},5000)
},
但是這里嘗試,發(fā)現(xiàn)嘗試了好多次之后發(fā)現(xiàn)目前在Service中不支持setTimout定時器的運行,還不知道是有意這么設(shè)計的還是缺陷bug,已經(jīng)反饋給華為官方進(jìn)行跟進(jìn)。那么只能換一種最low的方式來演示了,代碼如下:
onCommand(want, restart, startId) {
console.info('ServiceAbility onCommand');
featureAbility.terminateSelf();
}
最后運行日志截圖如下:
小結(jié)
在官方文檔基礎(chǔ)上,把操作步驟和一些關(guān)鍵解釋描述的更加詳細(xì),更加方便小白入手,防止入坑。
本篇只是入門級開胃小菜,我最終用這個Service的目的是為了在我智能家居的項目中,手機(jī)端通過該AbilityService實時接收服務(wù)端推送過來的數(shù)據(jù),然后Service中接收到服務(wù)端推送過來的數(shù)據(jù)之后可以主動更新UI對應(yīng)的Ability中的數(shù)據(jù),即需要打通Service主動向Activity中傳遞數(shù)據(jù)這個關(guān)鍵技術(shù)點。詳細(xì)打通流程會在下篇文章中講解,這個是目前官網(wǎng)上面沒有的內(nèi)容。