【Android 基础知识】服务 Service 基础

1、Service 的生命周期

  • 服务 Service 是 Android 的四大组件之一,常用在看不见页面的高级场合,例如闹钟服务、通知服务等。
  • Service 与 Activity 相比,不同之处在于没有对应的页面,相同之处在于有生命周期。

下面是 Service 与生命周期有关的方法:

  • onCreate:创建服务。
  • onStart:开始服务。Android 2.0 以下版本使用,已废弃。
  • onStartCommand:开始服务。Android 2.0 及以上版本使用。
  • onDestroy:销毁服务。
  • onBind:绑定服务。
  • onRebind:重新绑定。该方法只有当上次 onUnbind 返回 true 的时候才会被调用。
  • onUnbind:解除绑定。默认为 false。

Service 存在多种启停方法,每种启停方式都对应不同的周期方法,下面分别叙述 3 种启停方式及其生命周期说明:

  1. 普通启停

普通启停是最简单的用法,下面是该方式的服务代码:

public class NormalService extends Service {
    private static final String TAG = "NormalService";

    private void refresh(String text) {
        Log.d(TAG, text);
        ServiceNormalActivity.showText(text);
    }

    @Override
    public void onCreate() { // 创建服务
        refresh("onCreate");
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startid) { // 启动服务,Android2.0以下使用
        refresh("onStart");
        super.onStart(intent, startid);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) { // 启动服务,Android2.0以上使用
        Log.d(TAG, "测试服务到此一游!");
        refresh("onStartCommand. flags=" + flags);
        return START_STICKY;
    }

    @Override
    public void onDestroy() { // 销毁服务
        refresh("onDestroy");
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) { // 绑定服务。普通服务不存在绑定和解绑流程
        refresh("onBind");
        return null;
    }

    @Override
    public void onRebind(Intent intent) { // 重新绑定服务
        refresh("onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) { // 解绑服务
        refresh("onUnbind");
        return true;
    }

}

启动服务:
在这里插入图片描述
停止服务:
在这里插入图片描述

  1. 立即绑定

绑定方式的服务定义有所不同,因为绑定的服务可能运行于另一个进程,所以必须定义一个 Binder 对象用来进行进程间的通信。下面是一个绑定方式的服务代码:

public class BindImmediateService extends Service {
    private static final String TAG = "BindImmediateService";
    // 创建一个粘合剂对象
    private final IBinder mBinder = new LocalBinder();
    // 定义一个当前服务的粘合剂,用于将该服务黏到活动页面的进程中
    public class LocalBinder extends Binder {
        public BindImmediateService getService() {
            return BindImmediateService.this;
        }
    }

    private void refresh(String text) {
        Log.d(TAG, text);
        BindImmediateActivity.showText(text);
    }

    @Override
    public void onCreate() { // 创建服务
        refresh("onCreate");
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startid) { // 启动服务
        refresh("onStart");
        super.onStart(intent, startid);
    }

    @Override
    public void onDestroy() { // 销毁服务
        refresh("onDestroy");
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) { // 绑定服务。返回该服务的粘合剂对象
        Log.d(TAG, "绑定服务开始旅程!");
        refresh("onBind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) { // 重新绑定服务
        refresh("onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) { // 解绑服务。返回false表示只能绑定一次,返回true表示允许多次绑定
        Log.d(TAG, "绑定服务结束旅程!");
        refresh("onUnbind");
        return true;
    }
}

启动:
在这里插入图片描述
在这里插入图片描述
停止:
在这里插入图片描述
在这里插入图片描述

  1. 延迟绑定

延迟绑定与立即绑定的区别在于:延迟绑定是在页面上先通过 startService 方法启动服务,然后通过 bindService 方法绑定已存在的服务。这样,因为启动操作在先,所以解绑操作只能撤销绑定操作,而不能撤销启动操作。

由于解绑服务不能停止服务,因此存在再次绑定服务的可能。

public class BindDelayService extends Service {
    private static final String TAG = "BindDelayService";
    // 创建一个粘合剂对象
    private final IBinder mBinder = new LocalBinder();
    // 定义一个当前服务的粘合剂,用于将该服务黏到活动页面的进程中
    public class LocalBinder extends Binder {
        public BindDelayService getService() {
            return BindDelayService.this;
        }
    }

    private void refresh(String text) {
        Log.d(TAG, text);
        BindDelayActivity.showText(text);
    }

    @Override
    public void onCreate() { // 创建服务
        refresh("onCreate");
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startid) { // 启动服务
        refresh("onStart");
        super.onStart(intent, startid);
    }

    @Override
    public void onDestroy() { // 销毁服务
        refresh("onDestroy");
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) { // 绑定服务。返回该服务的粘合剂对象
        Log.d(TAG, "绑定服务开始旅程!");
        refresh("onBind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) { // 重新绑定服务
        refresh("onRebind");
        super.onRebind(intent);
    }

    @Override
    public boolean onUnbind(Intent intent) { // 解绑服务。返回false表示只能绑定一次,返回true表示允许多次绑定
        Log.d(TAG, "绑定服务结束旅程!");
        refresh("onUnbind");
        return true;
    }

}

启动:
在这里插入图片描述
绑定:
在这里插入图片描述
解绑:
在这里插入图片描述
停止:
在这里插入图片描述
从日志中可以看到,延迟绑定与立即绑定两种方式的生命周期区别在于:

  1. 延迟绑定的首次绑定操作只调用 onBind 方法,再次绑定只调用 onRebind 方法(是否允许再次绑定要看上次 onUnbind 方法的返回值)。
  2. 延迟绑定的解绑操作只调用 onUnbind 方法。

2、推送服务到前台

服务没有自己的布局文件,也就意味着无法直接在页面上显示,要想了解服务的运行情况,要么通过打印日志,要么获取某个页面的静态对象,然后在该页面上显示运行结果。然而活动页面有自身的生命周期,极有可能发生服务尚在运行但页面早已退出的情况,所以该方式不可靠。

服务内部的启停方法有对应的两个函数:

  • startForeground:把当前服务切换到前台运行。第一个参数表示通知的编号,第二个参数表示 Notification 对象,意味着切换到前台就是展示到通知栏。
  • stopForeground:停止前台运行。参数为 true 表示清除通知,参数为 false 表示不清除。

从 Android 9.0 开始,在服务中正常调用 startForeground 方法,还需修改 AndroidManifest.xml,添加如下所示的前台服务权限配置:

<!-- 允许前台服务 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玳宸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值