Service是Android四大组件之一,也是可执行的程序,有自己的生命周期。创建、配置Service和创建、配置Activity的过程相似。和Activity一样,都是从Context派生出来的。 ---《疯狂android讲义(第二版)》
就本地Service而言,通常有两种启动模式:start 和 bind。
一、start方式启动Service
使用Service的步骤:
1.定义一个类继承Service
![4115762-8329442f8d345cfc.png](https://i-blog.csdnimg.cn/blog_migrate/d266134a763a50ee44ba197f1d6136a6.png)
2.在Manifest.xml文件中配置该Service
![4115762-8d11184dbc14694e.png](https://i-blog.csdnimg.cn/blog_migrate/cea3ddfdcf0fc2790112dbfab5b53950.png)
3.使用Context的startService(Intent)方法启动该Service
![4115762-a5fa78c5e1c05ff1.png](https://i-blog.csdnimg.cn/blog_migrate/db54bdad2779e373bed4f8c7728d1f97.png)
4.不再使用时,调用stopService(Intent)方法停止该服务
![4115762-f7266c25dccb0c1b.png](https://i-blog.csdnimg.cn/blog_migrate/d64790287e0fe48926a65de022bcc324.png)
也可以让Service自身主动结束,在其内部调用stopSelf()
该方式下的生命周期:
onCreate();
onStartCommand();
onStart();(该方法已过时)
onDestroy();
![4115762-52f1a1a7ab24046b.png](https://i-blog.csdnimg.cn/blog_migrate/d23496f945d87fa295e9dfaa66784d92.png)
特点:这种方式下,开启者一旦开启Service之后,就与开启没有任何关系了,就算开启者挂掉,Service仍然会运行,开启者无法调用Service中的方法。
二、bind方式启动Service
1.定义一个类继承Service
同上
2.在Manifest.xml文件中配置该Service
同上
3.使用Context的bindService(Intent, ServiceConnection, int)方法启动该Service
![4115762-bf5ec0fc87429a3a.png](https://i-blog.csdnimg.cn/blog_migrate/90a639fcf1041e8c4869409fbf6342fa.png)
4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务
![4115762-f6470d8acc78a488.png](https://i-blog.csdnimg.cn/blog_migrate/137ae6eb412f9b32ef75243d162b2ac6.png)
该方式下Service的生命周期
onCreate();
onBind();
onUnbind():
onDestroy();
![4115762-3133094a8aba4438.png](https://i-blog.csdnimg.cn/blog_migrate/5a9d09dabbd4f1d8d1e7cffe88cb339d.png)
特点:这种方式下,Service不会调用onStartCommand() 和 onStart()方法。
绑定服务之后,调用者挂了,服务也会跟着挂,调用者可以调用服务中的方法。
如何调用服务中的方法?
绑定本地服务调用方法的步骤:
在服务的内部创建一个内部类 提供一个方法,可以间接调用服务的方法
实现服务的onbind方法,返回的就是这个内部类
在activity 绑定服务。bindService();
在服务成功绑定的回调方法onServiceConnected, 会传递过来一个 IBinder对象
强制类型转化为自定义的接口类型,调用接口里面的方法。
这里需要用到Binder和ServiceConnection。
首先在MyService中封装一个内部类,该类继承于Binder,实现了IMyBinder接口,目的在于给外部提供一个接口间接地调用服务内部的方法。
public class DownloadService extends Service {
private final String TAG = "DownloadService";
public DownloadService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"onCreate");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG,"onBind");
// TODO: Return the communication channel to the service.
return new MyBinder();
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG,"onUnbind");
return super.onUnbind(intent);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d(TAG,"onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand");
methodInMyService02();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
}
/**
* 该类用于在onBind方法执行后返回的对象,
* 该对象对外提供了该服务里的方法
/
private class MyBinder extends Binder implements IMyBinder{
@Override
public void invokeMethodInMyService() {
methodInMyService();
}
}
/*
* 服务内部方法1
/
private void methodInMyService() {
Log.d(TAG,"methodInMyService is called!!!");
}
/*
* 服务内部方法2
_/
private void methodInMyService02() {
new Thread(new Runnable() {
@Override
public void run() {
int i=0;
while(i<10)
{
Log.d(TAG,i++ + "");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stopSelf();
}
}).start();
}
}
_IMyBinder接口:*
![4115762-413310f10067d027.png](https://i-blog.csdnimg.cn/blog_migrate/84cbc3e9b3b4d5a080490ba5b6d5c354.png)
在MainActivity中封装一个内部类,继承于ServiceConnection,:
private MyConn myConn;
private IMyBinder myBinder;
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG,"onServiceConnected");
myBinder = (IMyBinder) iBinder; //因为确定是IMyBinder类型,所以将其强制转换。
invoke();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG,"onServiceDisconnected");
}
}
//调用服务内部方法
private void invoke()
{
myBinder.invokeMethodInMyService();
}
因为启动Service是,将Connection进行绑定,这样就可以通过返回IBinder间接地调用Service内部的方法了。