简评: 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 像弹簧同样动起来