Android前台服务和后台服务的区别

本节前言

Android四大组件之一服务(Service)的简单学习

Service的区别及分类
image.png

前台服务和后台服务最大的区别是:
1.前台Service在下拉通知栏有显示通知,但后台Service没有。
2.前台Service优先级较高,不会由于系统内存不足而被回收;后台Service优先级较低,当系统
出现内存不足情况时,很有可能会被回收。
有人可能会问,后台服务我们可以自己创建 ONGOING 的 Notification 这样就成为前台服务吗?答案是否定的,前台服务是在做了上述工作之后需要调用 startForeground ( android 2.0 及其以后版本 )或 setForeground (android 2.0 以前的版本)使服务成为 前台服务。这样做的好处在于,当服务被外部强制终止掉的时候,ONGOING 的 Notification 任然会移除掉。

Service生命周期
image.png
第一种方式:通过StartService启动Service

通过startService启动后,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。

要创建一个这样的Service,你需要让该类继承Service类,然后重写以下方法:

onCreate()
1.如果service没被创建过,调用startService()后会执行onCreate()回调;
2.如果service已处于运行中,调用startService()不会执行onCreate()方法。
也就是说,onCreate()只会在第一次创建service时候调用,多次执行startService()不会重复调用onCreate(),此方法适合完成一些初始化工作。

onStartCommand()
如果多次执行了Context的startService()方法,那么Service的onStartCommand()方法也会相应的多次调用。onStartCommand()方法很重要,我们在该方法中根据传入的Intent参数进行实际的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。

onBind()
Service中的onBind()方法是抽象方法,Service类本身就是抽象类,所以onBind()方法是必须重写的,即使我们用不到。

onDestory()
在销毁的时候会执行Service该方法。

这几个方法都是回调方法,且在主线程中执行,由android操作系统在合适的时机调用。

第二种方式:通过bindService启动Service

bindService启动服务特点:
1.bindService启动的服务和调用者之间是典型的client-server模式。调用者是client,service则是server端。service只有一个,但绑定到service上面的client可以有一个或很多个。这里所提到的client指的是组件,比如某个Activity。
2.client可以通过IBinder接口获取Service实例,从而实现在client端直接调用Service中的方法以实现灵活交互,这在通过startService方法启动中是无法实现的。
3.bindService启动服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。当然,client也可以明确调用Context的unbindService()方法与Service解除绑定。当没有任何client与Service绑定时,Service会自行销毁。

Android8.0后启动Service服务

Android在8.0开始限制后台服务,启动后台服务需要设置通知栏,使服务变成前台服务。同时在Android 9.0开始注册权限android.permission.FOREGROUND_SERVICE,并授权权限。
从8.0开始启动服务需要进行判断出来如下:

/**
 * Android 8.0及以后,启动服务的形式已经变了
 */
private void startService(Context context) {
    Intent intent = new Intent(context, MyForegroundService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(intent);
    } else {
        context.startService(intent);
    }
}

同时在Service的onCreate()方法里设置通知栏如下:

public class MyService extends Service {
@Override
public void onCreate() {
    super.onCreate();

    NotificationManager notificationManager = (NotificationManager)             
    getSystemService(Context.NOTIFICATION_SERVICE);
    //创建NotificationChannel
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
        NotificationChannel channel = new NotificationChannel(NOTIFICATION_ID,     
                  NOTIFICATION_NAME, NotificationManager.IMPORTANCE_HIGH);
        notificationManager.createNotificationChannel(channel);
    }
    //Android9.0会报Caused by: java.lang.SecurityException: Permission Denial:     
    //android.permission.FOREGROUND_SERVICE---AndroidManifest.xml中需要申请此权限
    startForeground(1,getNotification());
}
//这个必须加,不能设置为null
private Notification getNotification() {
    Notification.Builder builder = new Notification.Builder(this)
            .setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle("测试服务")
            .setContentText("我正在运行");//标题和内容可以不加
    //设置Notification的ChannelID,否则不能正常显示
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        builder.setChannelId(NOTIFICATION_ID);
    }
    Notification notification = builder.build();
    return notification;
}
}

说明:
测试发现Android8.0后如果用startService启动服务,应用退到后台后此服务一会儿就会被杀掉;如果用startForegroundService启动服务,并且添加了消息通知后,应用后台挂起则不会被系统杀掉

你可能感兴趣的:(Android前台服务和后台服务的区别)