jeffrey1995/MyBlog

Android-Service的基本用法

jeffrey1995 opened this issue · 0 comments

Service是Android四大组件之一,也是可执行的程序,有自己的生命周期。创建、配置Service和创建、配置Activity的过程相似。和Activity一样,都是从Context派生出来的。 ---《疯狂android讲义(第二版)》

就本地Service而言,通常有两种启动模式:start 和 bind。

一、start方式启动Service

使用Service的步骤
1.定义一个类继承Service
image

2.在Manifest.xml文件中配置该Service
image

3.使用Context的startService(Intent)方法启动该Service
image

4.不再使用时,调用stopService(Intent)方法停止该服务
image
也可以让Service自身主动结束,在其内部调用stopSelf()

该方式下的生命周期:
onCreate();
onStartCommand();
onStart();(该方法已过时)
onDestroy();
image

**特点:**这种方式下,开启者一旦开启Service之后,就与开启没有任何关系了,就算开启者挂掉,Service仍然会运行,开启者无法调用Service中的方法。

二、bind方式启动Service

1.定义一个类继承Service
同上
2.在Manifest.xml文件中配置该Service
同上
3.使用Context的bindService(Intent, ServiceConnection, int)方法启动该Service
image

4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务
image

该方式下Service的生命周期
onCreate();
onBind();
onUnbind():
onDestroy();
image

**特点:**这种方式下,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接口:*
image
在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内部的方法了。