Service两种启动方式和生命周期

两种启动方式启动service,要求:观察并打印生命周期方法、思考service的使用场景以及在什么情况下service会被回收

文章目录

  • 第一种启动方式——startService
      • 启动、停止服务
      • 运行结果
      • 结论和生命周期
  • 第二种启动方式——bindService
      • 绑定、解绑服务
      • 运行结果
      • 结论和生命周期
  • 重点问题
  • 参考

第一种启动方式——startService

启动、停止服务

  • MainActivity
@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_start:
                Intent startintent = new Intent(this, MyService.class);
                startService(startintent);  //启动服务
                break;
            case R.id.btn_stop:
                Intent stopintent = new Intent(this, MyService.class);
                stopService(stopintent);    //停止服务
                break;
                default:
                    break;
        }
    }
  • 新建service
public class MyService extends Service {

    private static final String TAG = "MyService";

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }
}
  • MainActivity.java

运行结果

Service两种启动方式和生命周期_第1张图片

  • 点击Start Service按钮,服务创建,启动
    在这里插入图片描述
  • 再点击Start Service按钮,服务启动
    在这里插入图片描述
  • 点击Stop Service按钮,服务停止
    在这里插入图片描述

结论和生命周期

生命周期:oncreate——>onstartCommand——>onDestroy

多次通过该方法启动Service,oncreate函数只会被调用一次,onStartCommand函数会被多次调用,但实际上每个服务都只会存在一个实例,所以只需要调用一次stopService就可以销毁该Service;

特点:通过该启动方式启动Service,一旦Service启动成功,该Service就会和他所创建的Activity脱离关系,也就是说Service的不会随着Activity的销毁而销毁,并且在应用的任何Activiy中都可以对该Service进行操作。

第二种启动方式——bindService

绑定、解绑服务

  • MyService.java
    创建一个专门的Binder对象来绑定服务端与客户端,新建DownloadBinder 类继承自Binder。在其内部写对服务进行操作的方法。可以在MainActivity中调用,由此来确认是否成功绑定服务。
    创建DownloadBinder 实例,在Service的onBind()方法中返回这个实例
public class MyService extends Service {

    private static final String TAG = "MyService";

    private DownloadBinder binder = new DownloadBinder();

    public MyService() {
    }

    class DownloadBinder extends Binder {

        public void startDownload() {
            Log.d(TAG, "startDownload: ");
        }

        public int getProgress() {
            Log.d(TAG, "getProgress: ");
            return 0;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.d(TAG, "onBind: ");
        return binder;
    }
    
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }
    
}
  • MainActivity.java

创建一个ServiceConnection 的匿名类,在里面重写onServiceConnected()和onServiceDisconnected()方法,分别在活动与服务绑定和解绑时调用。

在onServiceConnected方法中,通过向下转型得到了DownloadBinder 实例。现在可以调用DownloadBinder 中的方法。

此时,活动和服务还没绑定!!

	private MyService.DownloadBinder binder;
    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            binder = (MyService.DownloadBinder) iBinder;
            binder.startDownload();
            binder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };
  • onClick方法中

bindService()方法三个参数(Intent对象,ServiceConnection实例,标志位)

BIND_AUTO_CREATE——> 在活动和服务进行绑定后自动创建服务,即onCreate方法执行,但onStartCommand方法不执行。

	case R.id.btn_bind:
		Intent intent = new Intent(this, MyService.class);
		bindService(intent, connection, BIND_AUTO_CREATE);  //绑定服务
		break;
	case R.id.btn_unbind:
		unbindService(connection);  //解绑服务
		break;

运行结果

Service两种启动方式和生命周期_第2张图片

  • 点击Bind Service按钮
    在DownloadBinder中定义的两个方法都得到了执行,说明成功绑定。
    在这里插入图片描述
  • 点击unbind Service按钮
    在这里插入图片描述

结论和生命周期

生命周期:oncreate——>onBind——>unBind——>OnDestroy;多次bindService,oncreate和onBind方法都只会调用一次,而且只需要一次调用unBindService用于取消bind;

特点:它与startService正好相反,一个Activity通过bind的方式启动Service,那么该Service是依赖于该Activity存在的,也就是Activity的销毁也会导致bind所启动的Service的销毁(会经历unbind——>onDestroy的生命周期)

服务在整个应用程序范围内都是通用的,MyService可以和任何一个其他活动绑定,绑定完成后都可以获取到相同的DownloadBinder实例。

如果同时通过这两种方式进行启动,oncreate方法只会调用一次,在需要销毁Service的时候,需要同时调用stopService和unBindService(没有先后顺序)。

重点问题

现在系统对后台管控越来越严格
常规service一旦app退到后台很容易就被回收了
需要注意一下
网上有很多提高service优先级的方法,但是基本上都没用

重点关注service的特性和生命周期
基于service的这种特点,你可以想想service适合用在哪些场景

参考

两种启动方式区别

你可能感兴趣的:(Android)