作者提供的图片。
在Android世界中,服务的典型定义是在后台执行长时间任务的应用程序组件。它不提供用户界面。服务主要在主线程上运行,除非另有说明,我们应确保在服务中运行非阻塞操作。服务一直是Android组件的一部分,但是对它们进行了改进,以提供最佳的用户体验。
问题
服务在后台运行,可以从后台消耗位置、相机等资源。由于它没有任何用户界面,用户将不知道应用程序中正在运行哪些类型的服务以及正在消耗的资源。这对安全和性能都有影响。
这就是前台服务的作用。
在本文中,我们将了解前台服务是什么,为什么我们需要它以及如何实现它。
如果你想直接跳转到代码库,请查看GitHub仓库。
什么是前台服务?
前台服务只是执行用户可以注意到的任务的服务。为了通知用户,我们需要在状态栏中显示通知。这些通知的优先级应为PRIORITY_LOW
或更高。除非任务完成并且服务由于各种因素停止或删除自身或系统,否则不能删除通知。
这样,用户就会知道正在后台执行一些可能消耗系统资源的工作。
前台服务的一个简单示例是任何音频播放器应用程序。让我们以音乐播放器应用程序为例,即使应用程序未运行,也会在播放歌曲时显示通知。在这里,我们有一些控件可以与服务交互,在通知中显示与当前正在播放的歌曲相关的信息等。但是,通知仅在服务终止时才会被删除。
类似地,我们还可以看到交付应用程序在状态栏中显示订单跟踪的通知,Uber之类的出租车乘车应用程序如果行程正在进行中,则在通知中显示行程跟踪等。
我们为什么需要前台服务?
如果针对Android的应用程序尝试在应用程序未运行时使用正常服务执行后台操作,则系统将终止此服务,我们无法完成任务。为了平稳地处理后台事务,我们需要使用前台服务通知用户。
我们将在下面的示例中看到这一点,以更好地理解它。
如何实现前台服务
实现部分与服务的实现类似,但略有不同。让我们逐步了解如何实现它。
让我们创建一个示例应用程序,其中包含两个按钮(开始和停止)的活动和显示服务状态(运行或未运行)的文本视图。在这里,让我们还创建一个普通服务,测试它以了解问题,然后通过添加通知将服务迁移到前台服务。
步骤1
对于目标为Android 9(API级别28)或更高版本的应用程序,我们需要请求前台服务权限。我们需要在清单文件中指定以下权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
由于这是系统授予权限,因此无需进行其他处理。系统在清单中指定时会自动授予它。
注意:如果你在清单文件中启动前台服务而没有此权限,则系统会在运行时抛出SecurityException导致应用程序崩溃:
java.lang.SecurityException: Permission Denial: startForeground from pid=xxx, uid=xxxx requires android.permission.FOREGROUND_SERVICE
步骤2
让我们创建一个布局文件,其中包含两个按钮和一个文本视图。
步骤3
让我们创建一个简单的Service
类。当我们接收到ACTION_STOP
动作时,我们停止服务。
ACTION_STOP
只是分配任何值的常量。我已经给出以下值:
const val ACTION_STOP = "${BuildConfig.APPLICATION_ID}.stop"
步骤4
现在让我们创建一个Activity
,其中包含以下要求:
- 在单击启动按钮时,我们启动服务并在文本视图中更新状态。
- 在单击停止按钮时,我们停止服务并在文本视图中更新状态。
- 在
onCreate
中,我们在文本视图中更新服务状态。
检查服务是否正在运行
isMyServiceRunning
是一个实用方法。当我们给出一个类名时,我们可以通过使用ActivityManager
来检查服务是否正在运行。
现在运行应用程序并通过启动应用程序来检查输出。单击开始按钮并注意文本视图是否已更新。现在杀死应用程序,重新打开它,并检查文本视图中的服务状态是否处于停止状态。在面向Android 9(API级别28)或更高版本的设备上,默认情况下,Android系统会执行此操作。你可以尝试测试各种情况。
输出
步骤5
让我们通过添加通知、调用startForeground
并返回START_STICKY
,将我们的普通服务类迁移到前台服务。
START_STICKY
只是从onStartCommand
返回的常量。如果返回,则系统将在服务被杀死后尝试重新创建服务。
在这种情况下检查输出时,服务一旦启动,即使应用程序被杀死并重新启动,也不会停止。我们可以通过查看文本视图中显示的状态来检查这一点。我们应该手动停止它,在stopForeground
中传递true
时自动解除通知。传递布尔值是可选的,如果我们将其设置为true
,它将删除通知。## 输出
在这里,由于我们的服务是活动的而且没有停止,我们可以进行长时间运行的任务。同时,它显示通知以通知用户我们正在消耗系统资源。
如果你在执行代码段时遇到任何困难,请查看GitHub仓库。
总结
服务可以用于许多方式,但是将前台限制应用于服务会增加安全性和性能。根据你的需求使用前台服务。不要忘记在清单中添加FOREGROUND_SERVICE
权限。要启动前台服务,请调用startForeground()
。要停止它,请调用stopForeground()
。
感谢你的阅读。
资源
更多Android文章
译自:https://betterprogramming.pub/what-is-foreground-service-in-android-3487d9719ab6
评论(0)