Andorid:Service启动的两种方式及区别

Service介绍

Service是Android的四大组件之一,和Activity最大的区别是没有界面,是一个跑在后台的服务。
Service的两种启动方式:
startService启动,生命周期:
onCreate()——>onStartCommand()——>onDestroy()
bindService启动,生命周期:
onCreate()——>onBind()——>onUnbind()——>onDestroy()

Service启动方式

  1. startService启动
    使用这种方式开启的服务,服务开启后就和调用者没有任何关系了,之后调用者的生死不会影响服务的运行。调用者也不能用服务进行交互
    首次调用startService会依次调用onCreate()——>onStartCommand()
    服务启动后多次调用startService则只会多次回调onStartCommand()方法,onCreate()只会在启动是调用一次
    当服务需要退出时,需要调用stopService(可多次调用)或者调用服务内部的stopSelf,这时会回调onDestroy()方法

  2. bindService启动
    使用这种方式绑定的服务,服务的生死就和调用者的生死绑定到一起了,调用者销毁后,服务也会销毁但这种方式调用者可以
    和服务进行交互
    首次调用bindService会依次调用onCreate()——>onBind() ——>onServiceConnected()方法
    服务启动后多次调用bindService不会回调任何方法,即onCreate()和onBind()都只被调用一次
    当调用unbindService或调用者退出时,服务退出,则会回调onUnbind()——>onDestroy()

注意:多次调用unbindService,抛出java.lang.IllegalArgumentException: Service not registered

混合模式

先开启服务再绑定服务先绑定服务再开启服务

使用这种方式开启服务后,需要调用unbindService解绑服务、stopService停止服务,也可以先调用stopService再调用unbindService顺序不分先后,但都要调用。
如果直接退出调用者,这时相当于只调用了unbindService,此时Service只会回调onUnbind()方法,服务依然还在后台运行此时等同于startService方式启动了服务,直到调用了stopService或内存不足时才停止服务。

说明:Android系统仅会为一个Service创建一个实例对象,所以不管是启动服务还是绑定服务,操作都是同一个Service实例

Service使用

1、创建Service子类

public class TestService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("TestService:", "onCreate");
    }

    /*
    * 过时了推荐使用onStartCommand
    * */
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String value = intent.getStringExtra("twoActivity");
        Log.d("TestService:", "onStartCommand:" + value);
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        String value = intent.getStringExtra("twoActivity");
        Log.d("TestService:", "onUnbind:" + value);
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("TestService:", "onDestroy");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        String value = intent.getStringExtra("twoActivity");
        Log.d("TestService:", "onBind:" + value);
        //返回一个Binder对象
        return new MyBinder();
    }

    /**
     * 通过onBind方法把MyBinder对象返回给Activity,
     * 用于数据交换
     */
    public class MyBinder extends Binder {
        //提供一个方法给Activity调用
        public TestService1 getService() {
            // 返回TestService对象,这样就可以让Activity调用Service的公共方法了
            return TestService1.this;
        }
    }

    /**
     * 与Activity交互的接口
     */
    public String getMyName() {
        return "liuyunzhao";
    }
}
  1. 定义一个Service子类
  2. 在TestService类中创建一个MyBinder的内部类并继承Binder,并添加一个返回TestService对象的方法,用于和Activity进行交互
  3. 在onBind方法中返回一个MyBinder对象

说明:onStartCommand返回的是int值,一共有四个返回值,分别是:

START_STICKY:如果service因内存不足被系统kill掉,一段时间后内存再次空闲时,系统将尝试重新创建此Service,一旦创建成功后将回调onStartCommand方法,如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null

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

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

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启

2、创建Activity子类

首先在Activity中创建服务的连接对象ServiceConnection,用于与Service交互

private TestService mBindService; //绑定的Service对象
    /**
     * 服务连接对象
     */
private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("TestService:","onServiceConnected");
            TestService.MyBinder binder = (TestService.MyBinder) service;
            //拿到绑定的Service对象
            mBindService = binder.getService();
            String myName = mBindService.getMyName();
            Log.d("TestService:","myName="+myName);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("TestService:","onServiceDisconnected");
            mBindService = null;
        }
    };

onServiceConnected():绑定服务成功时被回调,通过这个方法可获取到从Service传递过来的IBinder对象,通过IBinder对象,可实现Activity与Service的交互

onServiceDisconnected():Service服务被杀死或意外崩溃时回调,如内存资源不足

注意:当客户端取消绑定时,系统不会调用该方法

2.1 多次调用startService

private void btn1Click() {
        Intent intent = new Intent(this, TestService.class);
        intent.putExtra("twoActivity", "startServiceData");
        startService(intent);
        startService(intent);
        startService(intent);
    }

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData

2.2 调用stopService

private void btn2Click() {
        Intent intent = new Intent(this, TestService.class);
        stopService(intent);
    }

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onDestroy

2.3 多次调用bindService

private void btn3Click() {
        Intent intent = new Intent(this, TestService.class);
        intent.putExtra("twoActivity", "bindServiceData");
        /*
        * 第一个参数是intent对象,表示开启服务
        * 第二个参数是绑定服务连接
        * 第三个参数是绑定时是否自动创建Service,BIND_AUTO_CREATE代表自动创建
        * */
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);
    }

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao

2.4 调用unbindService(不可多次调用)

private void btn4Click() {
        unbindService(connection);
    }

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy

2.5 先开启再绑定Service

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao

2.6 先解绑再停止服务

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy

2.7 先绑定再开启Service

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onCreate
com.cn.liuyz.servicedemo D/TestService:: onBind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onServiceConnected
com.cn.liuyz.servicedemo D/TestService:: myName=liuyunzhao
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData
com.cn.liuyz.servicedemo D/TestService:: onStartCommand:startServiceData

2.8 先解绑再停止服务

打印结果如下:

com.cn.liuyz.servicedemo D/TestService:: onUnbind:bindServiceData
com.cn.liuyz.servicedemo D/TestService:: onDestroy
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值