簡評: Android 實現後臺任務的最佳實踐。android
對於如今的應用來講,在應用生命週期以外運行一些後臺任務能夠說已是一項必不可少的需求了。這些任務多是在某個時間點提醒用戶什麼事情或同步本地數據到服務器等等。git
對此 Android 有一系列方式來實現這些後臺任務:github
JobSchedular 在 Lollipop (API level 21) 中被引入,也是目前實現後臺任務最有效的手段。其根據條件來執行任務,具體條件多是「設備鏈接上了網絡」、「正在充電」...服務器
官方文檔對此已經講得很詳細了。網絡
GCM Network Manager 提供的 API 和 JobSchedular 很類似,支持 API 9 及以上。惟一的問題就在因而屬於 Google Play Service SDK 的一部分,因此這裏就很少說了。app
JobSchedular 和 GCM Network Manager 能夠基於條件定義任務,好比網絡鏈接狀態改變、充電狀態改變,這些都不屬於會在某個固定時間點觸發的後臺任務。但有時你的應用可能須要在某個固定時間點觸發一個通知、週期性的任務什麼的。或者針對 API level 21 如下,又沒有集成 Google Play Service SDK 的應用實現一些後臺任務功能。這時就能夠考慮使用 AlarmManager。dom
碰見 Android-Jobide
能夠看到三個方案都有各自的優缺點,爲了解決這個問題,Evernote 開源了 Android-Job 這個很是出色的項目。ui
Android-Job 能根據當前系統的版本,是否集成 Google Play Service SDK 和要執行的任務類型調用不一樣的 API,兼容當前主流版本。this
集成:
apply plugin: 'com.android.application' android { ... } dependencies { ... compile 'com.evernote:android-job:1.1.8' }
使用:
Android-Job 主要包含了下面四個類/接口:
示例:
咱們來建立一個「展現通知任務」。首先,實現 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 來安排一個任務,任務的 tag 做爲一個任務的惟一標識。
其中 JobRequest 包含了不少的方法,都在項目的 Github 頁面中有詳細的說明。
以後,實現 JobCreator 接口:
class DemoJobCreator implements JobCreator { @Override public Job create(String tag) { switch (tag) { case ShowNotificationJob.TAG: return new ShowNotificationJob(); default: return null; } } }
能夠看到這裏是須要根據 Job 的 tag 來建立任務的。而後,在咱們應用的自定義 Application 類裏註冊 JobCreator :
public class MainApp extends Application { @Override public void onCreate() { super.onCreate(); JobManager.create(this).addJobCreator(new DemoJobCreator()); } }
最後,在須要的地方註冊任務:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ShowNotificationJob.schedulePeriodic(); } }
是否是很簡單。再也不須要本身去考慮什麼狀況該用哪一種方案了,只須要這樣統一的實現就能夠啦。
順便分享一個 debug 的小 tip。當咱們在 debug 的時候,每每會把間隔時間調短從而能夠立刻看到效果。可是在 Android N 中,規定了定時任務間隔最少爲 15 分鐘,若是小於 15 分鐘會獲得一個錯誤:intervalMs is out of range
這時,能夠調用 JobManager 的 setAllowSmallerIntervalsForMarshmallow(true)
方法在 debug 模式下避免這個問題。但在正式環境下必定要注意間隔時間設置爲** 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,讓應用的 View 像彈簧同樣動起來