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