美文网首页
组件——Service

组件——Service

作者: 四喜汤圆 | 来源:发表于2019-07-13 00:43 被阅读0次

一、作用

Android 四大组件之一,是Context类的子类。非常适合于执行不需要和用户交互,且要长期运行的任务。Service默认运行在 UI 线程,故,如果有耗时操作的话,开启子线程。

二、相关概念

1. Service 生命周期

  • onCreate()只能被回调一次,在其中进行初始化操作

  • onStartCommand()可被多次回调,每调用startService()启动服务一次就被回调一次,可将主要业务逻辑写在这个里面。

由于手机 RAM、资源有限,所以很多 Service 因为资源不足被 kill,此时,onStartCommand()的返回值决定了 Service 被 kill 后的处理方式(Android 综合揭秘 —— 全面剖释 Service 服务):

START_STICKY
如果service进程被kill掉,系统会尝试重新创建Service,如果在此期间没有任何启动命令被传递到Service,那么参数intent将为null。

START_NOT_STICKY
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT
使用这个返回值时,如果在执行完onStartCommand()后,服务被异常kill掉,系统会自动重启该服务,并将intent的值传入。

START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
而输入参数flags正是代表此次onStartCommand()方法的启动方式,正常启动时,flags默认为0,被kill后重新启动,参数分为以下两种:

START_FLAG_RETRY
代表service被kill后重新启动,由于上次返回值为START_STICKY,所以参数 intent 为null

START_FLAG_REDELIVERY
代表service被kill后重新启动,由于上次返回值为START_REDELIVER_INTENT,所以带输入参数intent

  • onBind()只能被回调一次,客户端通过调用bindService()时被回调,下次再调用bindService()不会回调该方法。通过该方法向客户端返回一个 IBinder实例,客户端通过该实例调用服务端的方法。

  • onUnBind()只能被回调一次,客户端通过调用unBindService()与服务端解除绑定时回调。若重复解绑会抛出异常。该方法默认返回 false, 当返回值 true 后,再次调用 Context.bindService 时将触发onRebind()方法

  • onRebind()

  • onDestroy()只能被回调一次,在其中完成资源清理工作,如取消注册监听器、关闭线程等。

2. 不同启动方式下 Service 的生命周期

按照启动方法将 Service 分类,不同启动方法下 Service 的生命周期不同。

生命周期

(1)startService()方式启动

  • 生命周期
    onCreate()->onStartCommand()->onDestroy()

  • 停止服务方法
    Service中调用stopSelf(),或启动者调用stopService()

(2)bindService

  • 生命周期
    onCreate()->onBind()->onUnBind()->onDestroy()

  • 停止服务方法:
    调用unbindService()来接触绑定;断开连接或调用该 Service 的 Context 不存在了,通过bindService()方法启动的 Service 的生命周期依附于启动它的 Context。

当 Service 和其他组件绑定时,Service 充当服务提供者的角色

(3)二者混合使用

  • 生命周期
    onCreate()->onStartCommand()->onBind()->onUnBind()->onDestroy()

  • 停止服务方法
    调用unBindService()将不会停止 Service,必须调用stopService()或 Service 自身的stopSelf()来停止服务。

三、使用

1. 后台运行的服务

public class BackService extends Service {
    private Thread mThread;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 在子线程中进行逻辑操作
        mThread = new Thread() {
            @Override
            public void run() {
                while (true) {
                    // 等待停止线程
                    if (this.isInterrupted()) {
                        try {
                            throw new InterruptedException();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                    // 耗时操作
                    System.out.println("xxx");
                }
            }
        };
        mThread.start();
        return super.onStartCommand(intent, flags, startId);

    }


    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 资源清理
        mThread.interrupt();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // 返回null
        return null;
    }
}
  • 新建类继承Service类,onBind()方法是Service类中的唯一一个抽象方法,必须要在子类中实现。

  • onStartCommand()中书写业务逻辑,本例中创建了子线程来完成耗时操作。

  • 当 Service 关闭后,如果在onDestory()方法中不关闭线程,你会发现我们的子线程进行的耗时操作是一直存在的,此时关闭该子线程的方法需要直接关闭该应用程序。因此,在onDestory()方法中要进行必要的清理工作。

  • 前台调用

Intent intent = new Intent(this, BackService.class);
// Intent 中携带数据
startService(intent);

2. 可交互的后台服务

当 Service 和其他组件绑定时,Service 充当服务提供者的角色。返回给客户端一个IBinder接口类型数据。

采用第一行代码中的实例。希望 DownloadService 提供下载功能,在 Activity 中可以决定下载何时开始,以及随时可以查看下载速度创建一个专门的Binder对象来对所提供的功能进行管理,Binder实现了IBinder接口

  • 创建提供服务的 Service
public class DowloadService extends Service {
    private DownloadBinder mBinder = new DownloadBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class DownloadBinder extends Binder {
        // 开始下载
        public void startDownload() {

        }

        // 下载进度
        public int getProgress() {
            return 0;
        }
    }
}
  • 客户端连接服务端,并调用服务端提供的方法
private DowloadService.DownloadBinder downloadBinder;

private ServiceConnection conn = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        // 绑定成功
        downloadBinder = (DowloadService.DownloadBinder) iBinder;
        // 调用服务端提供的方法
        downloadBinder.startDownload();
        downloadBinder.getProgress();
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        // 解除绑定

    }
};

public void download() {
    // 绑定service
    Intent intent = new Intent(this, DowloadService.class);
    bindService(intent, conn, BIND_AUTO_CREATE);

}

ServiceConnection:由服务使用者创建,以获取消息反馈。
onServiceConnected():活动与服务使用者绑定成功时回调,绑定成功后即可调用服务提供者 Service 的服务,通过 Binder 对象调用;onServiceDisconnected():解绑成功时回调

3. 前台服务

在状态栏有正在运行的系统图标。Service 启动后在状态栏开启一个通知。

@Override
public void onCreate() {
    super.onCreate();
    // ...
    startForeground(1, notifycation);
}

参考文献

lrh_Service

相关文章

网友评论

      本文标题:组件——Service

      本文链接:https://www.haomeiwen.com/subject/xwkhkctx.html