Service的两种启动方式

本文深入解析Android服务的概念,探讨其在后台任务执行中的角色,包括服务的生命周期、启动方式(如startService和bindService)、以及IntentService的使用。通过具体代码示例,帮助读者理解如何创建和管理服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务(Service)是Android中实现程序后台运行的解决方案,他非常适合去执行那些不需要和用户交互,而且还需要长期执行的任务。服务的运行不依赖任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用程序,服务仍然能够保持正常运行。不过需要注意的一点是,服务不是运行在一个独立的进程当中的,而是依赖创建服务时所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。
定义一个服务:

public class MyService extends Service {

    private static final String TAG = "MyService";
    @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 IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        //在绑定服务的时候调用
        return null;
    }

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

并且需要在AndroidManifest.xml文件中进行注册MyService类。
启动服务有两种方式,其中第一种是:
1、startService()

Intent mService = new Intent(this,MyService.class);
startService(mService);

其执行的生命周期是

onCreate()->onStartCommand()

停止服务的方法,一种是外部控制:(外部告诉Service该停止了)

stopService(mService);

一种是内部停止:(Service内部自己控制停止服务)

stopSelf()

如果多次调用startService()方法,onCreate()方法只会在第一次调用时执行,因此第一次服务还未被创建,但后续的调用onCreate()不会再执行,只会执行onStartCommand()方法。就算是多次执行startService()方法,也只会产生一个Service实例,因此只需要调用一次stopService()或者stopSelf()方法就可以停止服务了。
2、bindService()
启动服务的另外一种方式是绑定服务,由上面的启动方式可以看出,startService()只告诉了Service可以启动了,后续的任务完全由Service控制,这样活动和服务之间并没有什么通信,如果我们想要控制Service,想要和Service通信,那么就可以使用绑定服务的方式去开启。

//自定义Binder内部类,并通过onBind返回该对象
private MyBinder binder = new MyBinder();
public class MyBinder extends Binder {

        public void startDownload(){

        }
        public void getProgress(){

        }
 }
@Override
public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        //在绑定服务的时候调用
        return binder;
}

在活动中使用如下:

private MyService.MyBinder myBinder;
private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //活动与服务绑定时调用
            myBinder = (MyService.MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //活动与服务断开时调用
        }
};
Intent mService = new Intent(this,MyService.class);
//BIND_AUTO_CREATE表示活动与服务绑定之后自动创建服务
bindService(mService,connection,BIND_AUTO_CREATE);

其生命周期如下:

onCreate()->onBind()

就算是多次点击绑定服务,onBind方法和onCreate都只会调用一次,只需要调用一次unbindService就可以解绑服务了。

unbindService(connection);

另外需要注意的是,任何一个服务在整个应用程序范围内都是通用的,即MyService可以和MainActivity绑定,也可以和其他活动进行绑定,而且在绑定完成后获取到的是相同的MyBinder实例。
如果一个服务既调用了startService又调用了bindService,那么这种情况下该如何让服务停止销毁呢?根据Android系统的机制,一个服务只要被启动或者被绑定之后,就会一直处于运行状态,必须要让上述两个条件同时不满足,服务才能被销毁。即需要同时调用stopService和unbindService服务才会销毁。

3、IntentService
这个类是为了解决Service不能主动创建子线程、不能自动停止而提供的一个类,这个类很好的解决了上面的两种问题,可以实现异步,自动停止的服务。
这是一个抽象类,需要自定义一个IntentService类:

public class MyIntentService extends IntentService {

    private static final String TAG = "MyIntentService";
    public MyIntentService() {
        //提供一个无参的构造函数,内部必须调用父类的有参构造函数
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        //该方法在子线程中运行
        Log.d(TAG, "onHandleIntent: "+Thread.currentThread().getId());
    }

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

其中开启IntentService类的方式:

//对比IntentService中的onHandleIntent方法的线程
 Log.d(TAG, "buttonClick: "+Thread.currentThread().getId());
Intent intentService = new Intent(this,MyIntentService.class);
startService(intentService);

其运行结果是:

myapplication D/MainActivity: buttonClick: 2
myapplication D/MyIntentService: onHandleIntent: 1304
myapplication D/MyIntentService: onDestroy: 

可以看出IntentService确实实现了异步,自动结束的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值