Android 中高效執(zhí)行Schedule 任務(wù)(譯)

在目前的Application開發(fā)中蚂斤,執(zhí)行一些異步任務(wù)非常普遍栓拜,其中有些任務(wù)的執(zhí)行周期甚至超過了Application的生命周期狼纬,比如一些下載數(shù)據(jù)的任務(wù)或者一些更新網(wǎng)絡(luò)資源的任務(wù)晋柱。有時(shí)我們需要執(zhí)行一些非立即開始的任務(wù)砸讳。Android提供了一些可以在applications中明智使用的API琢融,用于 執(zhí)行一些預(yù)期后臺任務(wù)。

選擇一個合適執(zhí)行方式可以提高application 的性能簿寂,同時(shí)可以節(jié)省設(shè)備的電量損耗吏奸。

Android M引入了 Doze mode用于在用戶不使用手機(jī)一段時(shí)間后最大可能地節(jié)省電量。

以下是幾個Android提供的API:

  • Alarm Manager
  • Job Scheduler
  • GCM Network Manager
  • Firebase Job Dispatcher
  • Sync Adapter

使用Service的問題

Services允許在后臺長時(shí)間運(yùn)行任務(wù)陶耍。但是在后臺執(zhí)行Services相對來說比較耗電奋蔚。

Services即使不執(zhí)行什么有效的任務(wù),也會一直占用設(shè)備的資源烈钞。當(dāng)這些后臺Services監(jiān)聽系統(tǒng)的廣播時(shí)會加重以上的問題泊碑。

App運(yùn)行期的Schedule任務(wù)

在app運(yùn)行期執(zhí)行一些Schedule任務(wù)時(shí),推薦使用Handler配合Timer和Thread毯欣。這比使用Alarm Manager馒过, Job Scheduler等更簡單,也更高效酗钞。

App生命周期外的Schedule 任務(wù)

Alarm Manager

AlarmManager提供了系統(tǒng)級別alarm service的入口腹忽。它提供了在應(yīng)用運(yùn)行期外執(zhí)行操作的方法。AlarmManager可以在未來的某個時(shí)間啟動一個服務(wù)砚作,它可以在定時(shí)到達(dá)時(shí)觸發(fā)一個PendingIntent窘奏。

注冊后的alarm可以在設(shè)備鎖屏?xí)r依然是保留的(任務(wù)可以在設(shè)備鎖屏?xí)r觸發(fā)),但是在設(shè)備關(guān)閉或重啟之后就無效了葫录。

AlarmManager 可以在用于在特定時(shí)間觸發(fā)任務(wù)的操作着裹,并不提供其他更完善的執(zhí)行條件:如設(shè)備空閑、網(wǎng)絡(luò)可用或者開始充電等條件米同。

示例:當(dāng)我們需要在一個小時(shí)后或者每個小時(shí)執(zhí)行一些操作時(shí)骇扇,AlarmManager是一個不錯的選擇摔竿。但是無法在諸如網(wǎng)絡(luò)可用或者設(shè)備非充電狀態(tài)等狀態(tài)出現(xiàn)時(shí)觸發(fā)事件。

Job Scheduler

Job Scheduler 是所有提到的執(zhí)行預(yù)期任務(wù)首選的方式少孝,可以高效地執(zhí)行后臺任務(wù)继低。Job Scheduler API在Android 5.0(API 21)中引入的。

Job Scheduler運(yùn)行在設(shè)備有可用資源或者合適的條件時(shí)觸發(fā)任務(wù)稍走。在創(chuàng)建任務(wù)時(shí)可以自定義各種條件郁季。當(dāng)滿足生命的條件時(shí),系統(tǒng)將在app的 JobService中執(zhí)行定義的任務(wù)钱磅。Job Scheduler還可以根據(jù)Doze模式和應(yīng)用程序的待機(jī)限制執(zhí)行必要的操作梦裂。

用這種方式執(zhí)行任務(wù),可以讓設(shè)備長時(shí)間處于休眠狀態(tài)盖淡,從而延長電池使用時(shí)長年柠。一般來說Job Scheduler可以用來執(zhí)行對時(shí)間要求不嚴(yán)格的所有任務(wù)。

GCM Network Manager

GCM (Google Cloud Messaging)網(wǎng)絡(luò)管理擁有所有JobScheduler特性褪迟。GCM 網(wǎng)絡(luò)管理可以用于高效執(zhí)行所有重復(fù)或單次不緊急的任務(wù)冗恨,同時(shí)可以有效的節(jié)省設(shè)備電量。

它用于后向兼容味赃,可以在Android 5.0以下使用掀抹。在API 23及以上GCM實(shí)際使用了系統(tǒng)的JobSchedule。GCM 網(wǎng)絡(luò)管理使用了Google Play services中的scheduling 引擎心俗,因此只能在安裝了Google Play 的設(shè)備中使用傲武。

谷歌強(qiáng)烈建議GCM的用戶升級到FCM,使用Firebase Job Dispatcher執(zhí)行所有任務(wù)城榛。

Firebase Job Dispatcher

The Firebase JobDispatcher也是一個執(zhí)行后臺任務(wù)的庫揪利,它向后兼容(支持 API 21一下),可以在API 9+上運(yùn)行狠持。

The Firebase JobDispatcher可以運(yùn)行在未安裝Google Play 的設(shè)備上井仰。The Firebase JobDispatcher實(shí)際使用了AlarmManager嘴办,當(dāng)然如果設(shè)備安裝了Google Play,則The Firebase JobDispatcher使用Google Play中的Scheduling 引擎敛腌。

Sync Adapter

Sync Adapter設(shè)計(jì)用來同步本地和云端的數(shù)據(jù)泊藕。它只可以用來執(zhí)行這種任務(wù)搬男。在本地或者云端數(shù)據(jù)發(fā)生變化時(shí)可以觸發(fā)數(shù)據(jù)同步腺兴,或者定時(shí)觸發(fā)悼尾。Android系統(tǒng)會嘗試使用批量同步從而節(jié)省電量,未傳輸?shù)臄?shù)據(jù)將在隊(duì)列中等待同步昭齐。系統(tǒng)只會在聯(lián)網(wǎng)情況下嘗試進(jìn)行數(shù)據(jù)同步尿招。

當(dāng)然,還是建議盡可能使用JobScheduler, Firebase JobDispatcher, or GCM Network Manager等方法阱驾。

實(shí)踐

介紹了這么多就谜,我們來提供一個job scheduler的示例。

1. 創(chuàng)建 job service

繼承JobService來創(chuàng)建JobSchedulerService:

public class JobSchedulerService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}

JobService在main thread中執(zhí)行里覆,所有耗時(shí)邏輯應(yīng)在異步線程中丧荐。

同時(shí)還需要在AndroidManifest中注冊JobScheduler:

<application>
<service
android:name=”.JobSchedulerService “
android:permission=”android.permission.BIND_JOB_SERVICE”
android:exported=”true”/>
</application>

2. 創(chuàng)建一個JobInfo

創(chuàng)建JobInfo,如下所示需要傳遞 JobService喧枷。Job Builder允許創(chuàng)建job 執(zhí)行的多個條件虹统。

ComponentName serviceName = new ComponentName(context, JobSchedulerService.class);
JobInfo jobInfo = new JobInfo.Builder(JOB_ID, serviceName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.build();

3. 執(zhí)行任務(wù)

JobScheduler scheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
int result = scheduler.schedule(jobInfo);
if (result == JobScheduler.RESULT_SUCCESS) {
Log.d(TAG, “Job scheduled successfully!”);
}

可以在這里下載完整代碼:GitHub

總結(jié)

在執(zhí)行預(yù)期任務(wù)隧甚,需要仔細(xì)考慮執(zhí)行任務(wù)的時(shí)機(jī)车荔,選擇合適的方式,考慮應(yīng)用的運(yùn)行性能和節(jié)電性能戚扳。

JobScheduler非常方便使用忧便,同時(shí)即使在系統(tǒng)重啟后依然可以執(zhí)行。但是要注意JobScheduler要求API 21+帽借。

歡迎閱讀珠增,原文地址:https://android.jlelse.eu/schedule-tasks-and-jobs-intelligently-in-android-e0b0d9201777

歡迎關(guān)注公眾號wutongke,定期推送移動開發(fā)前沿技術(shù)文章:

wutongke
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砍艾,一起剝皮案震驚了整個濱河市蒂教,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脆荷,老刑警劉巖凝垛,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜓谋,居然都是意外死亡苔严,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門孤澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來届氢,“玉大人,你說我怎么就攤上這事覆旭⊥俗樱” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵型将,是天一觀的道長寂祥。 經(jīng)常有香客問我,道長七兜,這世上最難降的妖魔是什么丸凭? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上惜犀,老公的妹妹穿的比我還像新娘铛碑。我一直安慰自己,他們只是感情好虽界,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布汽烦。 她就那樣靜靜地躺著,像睡著了一般莉御。 火紅的嫁衣襯著肌膚如雪撇吞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天礁叔,我揣著相機(jī)與錄音牍颈,去河邊找鬼。 笑死琅关,一個胖子當(dāng)著我的面吹牛煮岁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播死姚,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼人乓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了都毒?” 一聲冷哼從身側(cè)響起色罚,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎账劲,沒想到半個月后戳护,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瀑焦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年腌且,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片榛瓮。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡铺董,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出禀晓,到底是詐尸還是另有隱情精续,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布粹懒,位于F島的核電站重付,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏凫乖。R本人自食惡果不足惜确垫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一弓颈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧删掀,春花似錦翔冀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菊匿。三九已至付呕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間跌捆,已是汗流浹背徽职。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佩厚,地道東北人姆钉。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像抄瓦,于是被迫代替她去往敵國和親潮瓶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容