交互式通信之Service

交互式通信之Service

我们知道Service是Android提供的一种后台运行机制的服务,主要运行在程序的后台,来完成不需要在前台显示的工作,比较常用,比如:后台的相关计算工作或是在后台运行监听程序等。那么这个后台组件是通过什么方式启动的那?

Service的启动方式分为两种(目前),分别为startService和bindService两种。启动的控制对象一般主要是通过Activity或者是Context(比如View等)来启动的。这两种启动方式所对应的Service的生命周期是不同的。下面即为Service的两种启动方式及不同的生命周期。如未说明一般是结合固有的属性方法来进行说明,这样更加易于理解和使用。具体可以参看下面的图形说明:


 

 

下面我以实际的例子来印证Service的两种启动方式的区别,这个例子就是在两种启动方式的Service中我们都使用线程来打印LOG日志,并通过是否打LOG来说明Service的生命周期是否结束(这只是为了说明),下面就来分析这两种启动方式下的Service的生命周期的区别。

startService启动方式:

在该启动方式下,Service的生命周期是这样的:当我们使用startService启动了Service之后,其生命周期:onCreate()->onStartCommand()->onStart(),当我们调用Service自身的stopSelf()或是stopService()的时候,其就会调用onDestroy()结束掉当前的Service,具体如下图:

 

如上图,当我们通过startService开启Service的时候,线程doTest一直打印LOG(红色部分1、2、3...),只有当我们调用stopService或是stopSelf的时候,Service停止运行并销毁(绿色部分),这就充分的说明了Service的声明周期。下面即为另一个问题,如果没有调用stopService或stopSelf,而是将启动该Service的Context关闭finish掉那?答案是该Service继续运行,如下图所示:

 

从上图可以看到,即时关掉了启动该Service的Context了,该服务还是继续运行,这就说明该服务Service并未与启动它的Context进行强关联(这与bindService正好相反)。下面列出以startService方式启动的源代码供参考:

public class MyStartService extends Service{

private static String TAG = "MyStartService";

private static boolean flag = false;

public static void runService(Context context) {

flag = true;

Intent intent = new Intent(context,MyStartService.class);

context.startService(intent);

}

@Override

public IBinder onBind(Intent intent) {

log("start_service_onbind");

return null;

}

 

@Override

public void onCreate() {

log("start_service_onCreate");

super.onCreate();

}

 

@Override

@Deprecated

public void onStart(Intent intent, int startId) {

log("start_service_onstart");

super.onStart(intent, startId);

}

 

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

log("start_service_onstartcommand");

doTest();

return super.onStartCommand(intent, flags, startId);

}

 

@Override

public void onDestroy() {

log("start_service_ondestroy");

flag = false;

super.onDestroy();

}

 

@Override

public boolean onUnbind(Intent intent) {

log("start_service_onunbind");

return super.onUnbind(intent);

}

 

@Override

public void onRebind(Intent intent) {

log("start_service_onrebind");

super.onRebind(intent);

}

public static void stopService(Context context) {

Intent intent = new Intent(context,MyStartService.class);

context.stopService(intent);

}

private void log(String log) {

Log.d(TAG,log);

}

private void doTest() {

new Thread() {

public void run() {

int mills = 0;

while(flag) {

try {

Thread.sleep(1000);

mills ++;

log(""+mills);

}catch(Exception e) {

e.printStackTrace();

}

}

}

}.start();

}

}

 

bindService启动方式:

在该启动方式下,Service的生命周期是这样的:当我们使用bindService开启服务的时候,是这样的:onCreate()->onBind(),而当我们调用unBindService的时候,其调用顺序:onUnBind()->onDestroy()结束掉该服务,具体如下图:

 

从上面的图中,我们可以看出当使用bindService开启服务时,线程doTest一致打印LOG,当我们调用unBindService时,才会结束掉当前的服务Service。那么如果当我们将启动该服务的Context关闭掉那?结果就会与以startService方式完全相反了,这个Service也会马上随着这个Context的结束而停止,具体如下图:

 

 

在该种启动方式下,使用bindService启动的服务Service是与启动它的Context发生了强关联,如果当前的Context结束了,那么这个Service也会停止,该部分的源代码如下:

public class MyBindService extends Service {

private static String TAG = "MyBindService";

private static boolean flag = false;

private static IBinder binder = new Binder();

private static ServiceConnection connection = new ServiceConnection(){

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

binder = service;

}

 

@Override

public void onServiceDisconnected(ComponentName name) {

binder = null;

}

};

public static void bindService(Context context) {

flag = true;

Intent intent = new Intent(context,MyBindService.class);

context.bindService(intent, connection, Context.BIND_AUTO_CREATE);

}

@Override

public IBinder onBind(Intent intent) {

log("bind_service_onbind");

doTest();

return binder;

}

 

@Override

public void onCreate() {

log("bind_service_onCreate");

super.onCreate();

}

 

@Override

@Deprecated

public void onStart(Intent intent, int startId) {

log("bind_service_onstart");

super.onStart(intent, startId);

}

 

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

log("bind_service_onstartcommand");

return super.onStartCommand(intent, flags, startId);

}

 

@Override

public void onDestroy() {

log("bind_service_ondestroy");

flag = false;

super.onDestroy();

}

 

@Override

public boolean onUnbind(Intent intent) {

log("bind_service_onunbind");

return super.onUnbind(intent);

}

 

@Override

public void onRebind(Intent intent) {

log("bind_service_onrebind");

super.onRebind(intent);

}

public static void stopService(Context context) {

context.unbindService(connection);

}

private void log(String log) {

Log.d(TAG,log);

}

private void doTest() {

new Thread() {

public void run() {

int mills = 0;

while(flag) {

try {

Thread.sleep(1000);

mills ++;

log(""+mills);

}catch(Exception e) {

e.printStackTrace();

}

}

}

}.start();

}

}

而对于onRebind()方法则在service和旧的client之间的所有捆绑联系在onUnbind里面全都结束之后,如果有一个新的client用bind连接上service,就会启动onRebind()方法。

 

到这里,关于Service的两种启动方式下其生命周期就分析完了,当然在这里的bindService方式下的Service绑定涉及到了进程间通信机制IBinder,这个会在后面的AIDL部分去分析,在这里我们只需知道它是负责进程间通信的机制即可。

注意:上面的两个Service需要在AndroidManifest中注册(省略)。

 

/**

* 欢迎加入技术群:179914858

* 如果有任何问题请在评论中进行讨论学习

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云水之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值