Android Service两种启动启动方式 及 adndroid service生命周期

来源:互联网 发布:软件测试兼职网站 编辑:程序博客网 时间:2024/05/16 05:06

startService:
正常调用:onCreate->onStart
取消绑定:onDestroy
如果调用者自己直接退出而没有调用stopService,则Service会一直在后台运行,直到下次调用者再启动起来,并明确调用stopService
bindService
正常调用:onCreate->onBind
取消绑定:onUnbind->onDestroy
先startService,再bindService
onCreate->onStart->onBind(onCreate只调用一次)
先stopService 再unbindService
点stopService不起作用,点unbindService后,立即输入2条:
onUnbind->onDestroy
如果先unbindService再stopService
则顺序输出:onUnbind->onDestroy
先bindService再startService
onCreate->onBind->onStart(onCreate只调用一次)
先stopService再unbindService
点stopService不起作用,点unbindService后,立即输入2条:
onUnbind->onDestroy
如果先unbindService再stopService
则顺序输出:onUnbind->onDestroy

=======================================================================

adndroid service生命周期:
  一、context.startService(Intent)调用:
      onCreate()-->onStart()
      1、onStart()后调用bindService该service则调用onBind(),调用onBind以后调stopService将无法释放该service必须再调unbindService才触发onUnbind()-->onDestroy()
         bindService后如果没有调用unbindService就退出activity,则只会调用unbind()方法,并且无法释该service
         结论:如果先startService再bindService,则只有调用unbindService和stopService了后才能释放该service,否则只调用其中一个无法释放该service
         释放顺序1:unbindService-->unBind()-->stopService-->onDestroy()
         释放顺序2:stopService-->unbindService-->unBind()-->onDestroy()
         释放顺序3:stopService-->推出active-->unBind()-->onDestroy()
      2、onStart()后调用unbindService,unbindService方法会抛异常,该service对象会消失,没有调用生命周期中得任何方法,
         异常抛出后会自动调用onCreate()-->onStart()创建对象
      3、onStart()后调用stopService释放该service,执行顺序:onDestroy()
      4、onStart()后调用startService不会创建新的service,执行顺序:onStart()
      执行顺序列表(on开头的方法位service生命周期方法,其他为context对象方法):
      1、context.startService(Intent)-->onCreate()-->onStart()-->context.unbindService()(方法会抛异常)-->onCreate()-->onStart()
      2、context.startService(Intent)-->onCreate()-->onStart()-->context.stopService-->onDestroy()
      3、context.startService(Intent)-->onCreate()-->onStart()-->context.startService-->onStart()
      
      4、context.startService(Intent)-->onCreate()-->onStart()-->context.bindService()-->onBind-->context.unbindService-->unBind()-->context.stopService-->onDestroy()
      5、context.startService(Intent)-->onCreate()-->onStart()-->context.bindService()-->onBind-->context.stopService-->context.unbindService-->unBind()-->onDestroy()
      6、context.startService(Intent)-->onCreate()-->onStart()-->context.bindService()-->onBind-->context.stopService-->退出active-->unBind()-->onDestroy()
  二、context.bindService()调用:   
  
      1、context.bindService()-->onCreate()-->onBind()-->context.unbindService()-->unBind()-->onDestroy()
      2、context.bindService()-->onCreate()-->onBind()-->context.stopService
      3、context.bindService()-->onCreate()-->onBind()-->context.startService-->onStart()
      
      4、context.bindService()-->onCreate()-->onBind()-->context.startService()-->context.unbindService-->unBind()-->context.stopService-->onDestroy()
      5、context.bindService()-->onCreate()-->onBind()-->context.startService()-->context.stopService-->context.unbindService-->unBind()-->onDestroy()
      6、context.bindService()-->onCreate()-->onBind()-->context.startService()-->context.stopService-->退出active-->unBind()-->onDestroy()   
      
综合以上2点,在对service调用时最好只用一种方式,start或者bind,如果使用了2种方式,2种方式得到的是同一个service对象,并且必须是2种方式都调用了退出方式才能释放service
bind方式默认退出activity则启动释放service


在android音乐播放器的源码中,启动播放Service的源码先使用了startService, 然后又使用了bindService, 代码如下:


[java] view plaincopyprint?
public static ServiceToken bindToService(Activity context, ServiceConnection callback) {  
        Activity realActivity = context.getParent();  
        if (realActivity == null) {  
            realActivity = context;  
        }  
        ContextWrapper cw = new ContextWrapper(realActivity);  
        <span style="color:#FF0000;">cw.startService(new Intent(cw, MediaPlaybackService.class));</span>  
        ServiceBinder sb = new ServiceBinder(callback);  
        if (<span style="color:#FF0000;">cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)</span>) {  
            sConnectionMap.put(cw, sb);  
            return new ServiceToken(cw);  
        }  
        Log.e("Music", "Failed to bind to service");  
        return null;  
    }  
public static ServiceToken bindToService(Activity context, ServiceConnection callback) { Activity realActivity = context.getParent(); if (realActivity == null) { realActivity = context; } ContextWrapper cw = new ContextWrapper(realActivity); <span style="color:#FF0000;">cw.startService(new Intent(cw, MediaPlaybackService.class));</span> ServiceBinder sb = new ServiceBinder(callback); if (<span style="color:#FF0000;">cw.bindService((new Intent()).setClass(cw, MediaPlaybackService.class), sb, 0)</span>) { sConnectionMap.put(cw, sb); return new ServiceToken(cw); } Log.e("Music", "Failed to bind to service"); return null; }
使用startService可以保证在音乐播放Activity退出后播放音乐的服务仍继续运行,而bindService则保证了Activity能够和Service进行交互。

1. 使用startService启动服务的生命周期方法:

使用这种方法启动一个Service,在Service启动后该Service和启动该Service的Activity就没有关系了。但是这种发放启动的Service不能和Activity进行交互。

通常情况下使用startService调用的Service生命周期方法为:onCreate()->onStartCommand()。

其中多次调用startService只调用一次onCreate(), 但可以多次调用onStartCommand().

当服务需要退出时,调用stopService,就会调用Service的onDestroy()方法。

2.使用bindService启动服务的生命周期方法:

使用这种方法启动的Service是和调用者Activtiy同生命的,当Activtiy退出时,服务也同时销毁了。这种方法启动的Service能够和Activity进行交互。

调用bindService启动服务,Service生命周期方法为:onCreate()->onBind()

多次调用bindService并不会多次调用onBind(), 即onCreate()和onBind()都是只被调用一次。

当Activity退出是,该Service销毁,调用:onUnbind()->onDestroy();

3. 综合以上两点,在音乐播放器的源码中先调用startService再调用bindService()调用的Service生命周期方法顺序为:

onCreate()->onStartCommand()->onBind().

此时如果没有播放音乐,就退出Activity,调用的方法为:

onUnbind()->onDestroy();

如果第一次启动音乐播放器后播放了一首音乐,在播放的过程中退出Activity, 此时调用的方法为:

onUnbind();

这种情况下只是解除了Activity与Service之间的绑定,Service仍再后台运行继续播放音乐。

此时再运行播放器程序,调用的方法为:

onStartCommand()->onRebind();

这里调用onStartCommand()容易理解,调用onRebind()的原因是在onUnbind()发放中返回了true, 返回true表示当服务再次被绑定时调用服务的onRebind()方法。

此时停止播放,并退出播放器程序,调用的方法为:

onUnbind();

此方法是马上调用的,系统并没有马上调用Service的onDestroy()方法,但是过了大约1分钟后又调用了Service的onDestroy()方法。从设置中查看正在运行的服务也可以验证这一点,在音乐播放器在无播放状态下退出后,刚开始音乐播放器服务仍然存在,大概1分钟后该服务就不存在了。这点是为什么我也没有弄明白,为什么在onUnbind()之后没有马上调用onDestroy(),而是在过了一段时间之后才调用onDestroy(), 难道是android系统自己发现是一个空服务,就把他销毁了,有谁知道原因是什么,希望大家告诉我下,谢谢!

0 0
原创粉丝点击