详细博客https://www.cnblogs.com/codingblock/p/4842224.html
2.1:启动方式是 startService
Service的生命周期:onCreate() --> onStartcommand() -> onDestroy()
停止服务:stopService()
2.2:启动方式是 bindService
Service的生命周期 onCreate() --> onBind() --> onUnBind() --> onDestroy()
停止服务:UnbindService()再StopService()
区别:使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。而且使用bindService是可以操作和Service传递数据的
一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又bindService,Service只被创建一次。如果先是bind了,那么start的时候就直接运行Service的onStartcommand方法,如果先是start,那么bind的时候就直接运行onBind方法。
因为android发展到现阶段,需要前端写本地service的项目越来越少,那么讲了那么多理论,下面我们通过具体代码来弄清楚Service的创建以及启动:
3.1.1 继承Service,创建Service子类。
3.1.2 在AndroidManifest.xml文件中配置该Service。
下面创建一个最基本的Service组件:
MyService.java
public class MyService extends Service {
//必须实现的方法,用户返回Binder对象
@Override
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return null;
}
//创建Service时调用该方法,只调用一次
@Override
public void onCreate() {
super.onCreate();
System.out.println("--onCreate()--");
}
//每次启动Servcie时都会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("--onStartCommand()--");
return super.onStartCommand(intent, flags, startId);
}
//解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println("--onUnbind()--");
return super.onUnbind(intent);
}
//退出或者销毁时调用该方法
@Override
public void onDestroy() {
System.out.println("--onDestroy()--");
super.onDestroy();
}
}
然后再Manifest.xml文件中红配置一下
为了待会测试的方便,我们在该Service的onCreate()方法里面写一个方法,开启一个线程,让其不断输出“Service运行中”的状态。补充后的MyService类如下:
public class MyService extends Service {
private boolean serviceRunning = false;
// 必须实现的方法,用户返回Binder对象
@Override
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return null;
}
// 创建Service时调用该方法,只调用一次
@Override
public void onCreate() {
super.onCreate();
System.out.println("--onCreate()--");
serviceRunning = true;
new Thread() {
@Override
public void run() {
while (serviceRunning) {
System.out.println("---Service运行中---");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
// 每次启动Servcie时都会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("--onStartCommand()--");
return super.onStartCommand(intent, flags, startId);
}
// 解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
System.out.println("--onUnbind()--");
return super.onUnbind(intent);
}
// 退出或者销毁时调用该方法
@Override
public void onDestroy() {
serviceRunning = false;
System.out.println("--onDestroy()--");
super.onDestroy();
}
}
代码分析:首先我们定义一个boolean类型的变量serviceRunning,用来控制新线程中是否输出“—Service运行中—”,通过这样的方式更能让我们直观地看到Servcie的运行状态。
3.2:启动Service
启动Service和启动一个Activity类似,也是先定义一个Intent让它指向需要启动Service,然后通过调用startService()方法,启动即可,具体代码如下:
btn_start_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
intent = new Intent(this, MyService.class);
startService(intent);
}
});
3.3:停止Service
btn_stop_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
stopService(intent);
}
});
3.4:绑定Service
绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动Service比起来,会麻烦一些,大体分为如下三步:
第一步:重写onBind()方法,返回Service实例
Service可以让Activity绑定,以获得更加详细的接口。如果先想让一个Service支持绑定,需要实现 Service中得onBind()方法,并返回被绑定Service的当前实例,如下:
public IBinder onBind(Intent intent) {
System.out.println("--onBind()--");
return new MyBinder();
}
public class MyBinder extends Binder{
MyService getService(){
return MyService.this;
}
第二步:实现一个ServiceConnection
另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写onServiceConnected()方法和onServiceDisconnected()方法,来获得对Service实例的引用。代码如下:
MyService.MyBinder binder = null;
class MyServiceConn implements ServiceConnection {
// 服务被绑定成功之后执行
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//service为onBind方法返回的Service实例
binder = (MyService.MyBinder) service;
}
// 服务奔溃或者被杀掉执行
@Override
public void onServiceDisconnected(ComponentName name) {
binder = null;
}
}
第三步:调用bindService执行绑定Service
要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection实例外,还需要指定一个标示,如下:
btn_bind_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE);
}
});
其中,myServiceConn为第二步中MyServiceConn实例,Context.BIND_AUTO_CREATE即为标示。
3.5、解绑Service
解绑Service是通过unbindService实现的,如下:
btn_unbind_service.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (binder != null) {
unbindService(myServiceConn);
}
}
});
主界面简单,只有四个按钮,如下:
1、当按下startService按钮,然后再按下stopService按钮时,日志如下:
2、当按下bindService,然后再按下unbindService时,日志如下:
3、当按下startService接着按bindService时,这时候就需要unbindService和stopService都按下后才能停止Service,日志如下:
启动Service和停止Service是一一对应的,绑定Service和解绑Servcie是一一对应的,如果同时启动和绑定了Service,必须通过解绑和停止Service才能使该Service真正停止。