摘要:對此有一系列方式來實現(xiàn)這些后臺任務(wù)在中被引入,也是目前實現(xiàn)后臺任務(wù)最有效的手段。目前已更新為提供的和很相似,支持及以上。但在正式環(huán)境下一定要注意間隔時間設(shè)置為分鐘以上。
簡評: Android 實現(xiàn)后臺任務(wù)的最佳實踐。
對于現(xiàn)在的應(yīng)用來說,在應(yīng)用生命周期之外運行一些后臺任務(wù)可以說已經(jīng)是一項必不可少的需求了。這些任務(wù)可能是在某個時間點提醒用戶什么事情或同步本地數(shù)據(jù)到服務(wù)器等等。
對此 Android 有一系列方式來實現(xiàn)這些后臺任務(wù):
1. JobSchedularJobSchedular 在 Lollipop (API level 21) 中被引入,也是目前實現(xiàn)后臺任務(wù)最有效的手段。其根據(jù)條件來執(zhí)行任務(wù),具體條件可能是「設(shè)備連接上了網(wǎng)絡(luò)」、「正在充電」...
官方文檔對此已經(jīng)講得很詳細(xì)了。
2. GCM Network Manager(目前已更新為 FCM)GCM Network Manager 提供的 API 和 JobSchedular 很相似,支持 API 9 及以上。唯一的問題就在于是屬于 Google Play Service SDK 的一部分,所以這里就不多說了。
3. AlarmManagerJobSchedular 和 GCM Network Manager 可以基于條件定義任務(wù),比如網(wǎng)絡(luò)連接狀態(tài)改變、充電狀態(tài)改變,這些都不屬于會在某個固定時間點觸發(fā)的后臺任務(wù)。但有時你的應(yīng)用可能需要在某個固定時間點觸發(fā)一個通知、周期性的任務(wù)什么的。或者針對 API level 21 以下,又沒有集成 Google Play Service SDK 的應(yīng)用實現(xiàn)一些后臺任務(wù)功能。這時就可以考慮使用 AlarmManager。
遇見 Android-Job
可以看到三個方案都有各自的優(yōu)缺點,為了解決這個問題,Evernote 開源了 Android-Job 這個非常出色的項目。
Android-Job 能根據(jù)當(dāng)前系統(tǒng)的版本,是否集成 Google Play Service SDK 和要執(zhí)行的任務(wù)類型調(diào)用不同的 API,兼容當(dāng)前主流版本。
集成:
apply plugin: "com.android.application" android { ... } dependencies { ... compile "com.evernote:android-job:1.1.8" }
使用:
Android-Job 主要包含了下面四個類/接口:
Job:所有我們的 Job 都需要繼承它,并實現(xiàn) onRunJob 方法。
JobRequest:用來定義一個具體的任務(wù)(Job)。
JobCreator:根據(jù)任務(wù)的 tag 來創(chuàng)建任務(wù)。
JobManager:android-job 的入口。
示例:
我們來創(chuàng)建一個「展示通知任務(wù)」。首先,實現(xiàn) Job:
class ShowNotificationJob extends Job { static final String TAG = "show_notification_job_tag"; @NonNull @Override protected Result onRunJob(Params params) { PendingIntent pi = PendingIntent.getActivity(getContext(), 0, new Intent(getContext(), MainActivity.class), 0); Notification notification = new NotificationCompat.Builder(getContext()) .setContentTitle("Android Job Demo") .setContentText("Notification from Android Job Demo App.") .setAutoCancel(true) .setContentIntent(pi) .setSmallIcon(R.mipmap.ic_launcher) .setShowWhen(true) .setColor(Color.RED) .setLocalOnly(true) .build(); NotificationManagerCompat.from(getContext()) .notify(new Random().nextInt(), notification); return Result.SUCCESS; } static void schedulePeriodic() { new JobRequest.Builder(ShowNotificationJob.TAG) .setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(5)) .setUpdateCurrent(true) .setPersisted(true) .build() .schedule(); } }
可以看到其中我們通過 JobRequest 來安排一個任務(wù),任務(wù)的 tag 作為一個任務(wù)的唯一標(biāo)識。
其中 JobRequest 包含了很多的方法,都在項目的 Github 頁面中有詳細(xì)的說明。
之后,實現(xiàn) JobCreator 接口:
class DemoJobCreator implements JobCreator { @Override public Job create(String tag) { switch (tag) { case ShowNotificationJob.TAG: return new ShowNotificationJob(); default: return null; } } }
可以看到這里是需要根據(jù) Job 的 tag 來創(chuàng)建任務(wù)的。然后,在我們應(yīng)用的自定義 Application 類里注冊 JobCreator :
public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); JobManager.create(this).addJobCreator(new DemoJobCreator()); } }
最后,在需要的地方注冊任務(wù):
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ShowNotificationJob.schedulePeriodic(); } }
是不是很簡單。不再需要自己去考慮什么情況該用哪種方案了,只需要這樣統(tǒng)一的實現(xiàn)就可以啦。
順便分享一個 debug 的小 tip。當(dāng)我們在 debug 的時候,往往會把間隔時間調(diào)短從而可以馬上看到效果。但是在 Android N 中,規(guī)定了定時任務(wù)間隔最少為 15 分鐘,如果小于 15 分鐘會得到一個錯誤:intervalMs is out of range
這時,可以調(diào)用 JobManager 的 setAllowSmallerIntervalsForMarshmallow(true) 方法在 debug 模式下避免這個問題。但在正式環(huán)境下一定要注意間隔時間設(shè)置為 15 分鐘以上。
public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); JobManager.create(this).addJobCreator(new DemoJobCreator()); JobManager.instance().getConfig().setAllowSmallerIntervalsForMarshmallow(true); // Don"t use this in production } }
原文鏈接:Easy Job Scheduling with Android-Job
推薦閱讀:Android - Spring Animation,讓應(yīng)用的 View 像彈簧一樣動起來
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74830.html
摘要:題目描述團隊在月日搬入了學(xué)清嘉創(chuàng)大廈,為慶祝團隊的喬遷之喜,字節(jié)君決定邀請整個團隊,舉辦一個大型團建游戲字節(jié)跳動大闖關(guān)。這個人每個人都向字節(jié)君提供了自己認(rèn)識的人的名字,不包括自己。其他所有人均刻意直接或間接的認(rèn)識,分在同一組。 題目描述 Bytedance Efficiency Engineering團隊在8月20日搬入了學(xué)清嘉創(chuàng)大廈,為慶祝團隊的喬遷之喜,字節(jié)君決定邀請整個EE團隊,...
摘要:重新認(rèn)識三如果被推遲執(zhí)行的回調(diào)函數(shù)是某個對象的方法,那么該方法中的關(guān)鍵字將指向全局環(huán)境,而不是定義時所在的那個對象。 重新認(rèn)識一 一般,setTimeout函數(shù)接受兩個參數(shù),第一個參數(shù)func|code是將要推遲執(zhí)行的函數(shù)名或者一段代碼(引擎內(nèi)部使用eval函數(shù),將字符串轉(zhuǎn)為代碼),第二個參數(shù)delay是推遲執(zhí)行的毫秒數(shù)。但是,setTimeout 還可以添加更多參數(shù)。第二個之后的參數(shù)...
摘要:前言今天,為表達我對前端的熱愛,特此發(fā)了一篇小總結(jié)。其實這是一種很籠統(tǒng)的說法,因為綁定監(jiān)聽事件的方式不同,可能情況不一樣。但是不論怎樣,這么寫準(zhǔn)沒錯。監(jiān)聽的綁定方式為了方便描述現(xiàn)象。火狐一般會自動更新為最新版的,所以前的顧慮基本上沒有了。前言 今天520,為表達我對前端的熱愛,特此發(fā)了一篇小總結(jié)。實際上你看不看這文章,對你目前來講,其實也沒多大影響,這是我的真心話哈哈 剛學(xué)前端的時候,有很多...
摘要:方法即為收集器,它接收高階函數(shù)和的后端掘金年的第一天,我坐在獨墅湖邊,寫下這篇文章。正因如此,所以最全系列教程后端掘金是從版本開始引入的一個新的,可以替代標(biāo)準(zhǔn)的。 設(shè)計模式之單例模式 - 掘金前言 作為一個好學(xué)習(xí)的程序開發(fā)者,應(yīng)該會去學(xué)習(xí)優(yōu)秀的開源框架,當(dāng)然學(xué)習(xí)的過程中不免會去閱讀源碼,這也是一個優(yōu)秀程序員的必備素養(yǎng),在學(xué)習(xí)的過程中很多人會遇到的障礙,那就是設(shè)計模式。很多優(yōu)秀的框架會運...
閱讀 2452·2021-11-22 09:34
閱讀 3063·2021-10-25 09:43
閱讀 1975·2021-10-11 10:59
閱讀 3361·2021-09-22 15:13
閱讀 2324·2021-09-04 16:40
閱讀 418·2019-08-30 15:53
閱讀 3186·2019-08-30 11:13
閱讀 2602·2019-08-29 17:30