Service知识点总结

来源:互联网 发布:阿里云os刷机包下载 编辑:程序博客网 时间:2024/06/07 07:17

一、Service生命周期(两种途径):

       1>onCreate()--->onStartCommand()--->(onStart())--->onDestroy()

          被开启的service通过其他组件调用 startService()被创建。
            这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它。无论调用了多少次startService(),都 只需调用一次 stopService()来停止。         
            当service被停止时,系统会销毁它。

       2>onCreate()--->onBind()--->onUnbind()--->onDestory()

          被绑定的service是当其他组件(例如:TestActivity)调用bindService()来创建的。
          TestActivity可以通过一个IBinder接口和service进行通信[下面会简单介绍和Activity之间传递数据]
          TestActivity可以通过unbindService()方法来关闭这种连接。
           一个service可以同时和多个Activity绑定,当多个Activity都解除绑定之后,系统会销毁service。


注意:onStartComand使用时,返回的是一个(int)整型。有四个返回值类型:  START_STICKY、START_NO_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY

1>START_STICKY: 如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由 于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传 递到service,那么参数Intent将为null。  

2>START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务  

3>START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。   

4>START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

 

当然这两种方式并不是完全分开的,你还可以将一个已经strartService的服务进行绑定,例如:一个后台播放器服务通过startService被启动来播放音乐,可能在播放过程中用户要执行一些操作或者获取一些歌曲信息,此时可以通过bingService与Service建立连接,这种情况下stopService()或 stopSelf()实际上并不能停止这个service,直到最后一次绑定关闭

二、IntentService

       服务中的代码都是默认都是运行在主线程当中 ,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR ( Application Not Responding ) 的情况。
所以这个时候就需要用到Android多线程编程的技术了,我们应该在服务的每个具体的方法 里开启一个子线程,然后在这里去处理那些耗时的逻辑。因此,一个比较标准的服务就可以写成 如下形式:

public class MyService extends Service {    @Override    public int onStartCommand(Intent intent, int flags, int startld) {        new Thread(new Runnable() {            @Override            public void run() {                //处理具体的逻辑操作            }        }).start();        return super.onStartCommand(intent, flags, startld);    }}
但是,服务一旦启动就会一直运行,必须调用stopSelf或者stopService才会停止,所以要想让一个服务执行完逻辑操作之后自动关闭,就需要调用stopSelf(); 如下:

public class MyService extends Service {    @Override    public int onStartCommand(Intent intent, int flags, int startld) {        new Thread(new Runnable() {            @Override            public void run() {                //处理具体的逻辑
                 stopSelf();            }        }).start();        return super.onStartCommand(intent, flags, startld);    }}
因此,为了避免忘记开启线程或者手动关闭服务,Android专门提供了IntentService:

public class MyService extends IntentService{    //必须要有此构造方法,在其内部调用父类的有参构造函数    public MyService() {        super("MyService");    }
    //该方法在子线程中运行,不用再手动开辟线程    @Override    protected void onHandleIntent(@Nullable Intent intent) {    }
    //服务执行完会自动调用该方法停止,不用在手动关闭服务    @Override    public void onDestroy() {        super.onDestroy();    }
}

IntentService集开启线程和自动停止于一身,得到了不少程序员的喜爱。


三、Android中Service与Activity数据交互:

       1>通过startService()与stopService()启动和停止服务,Service与启动它的Activity无法进行通信和数据交换 

       2>通过bindService(Intent, ServiceConnection, int)与unbindService(ServiceConnection)启动和停止服务

       注意:类ServiceConnection中的onServiceDisconnected()方法在正常情况下是不会被调用的,它的调用时机是当   Service服务被异外销毁时,例如内存的资源不足时.   另外,多个客户端可以绑定同一个服务,如果Service还未被启动,bindService()方法可以启动服务。


要进行数据交互:

首先创建一个Service中,并在创建Service类时,创建一个bind对象,在onBind方法中返回
private TempService.MyBinder binder;

public class TempService extends Service{    private MyBinder myBinder=new MyBinder();    public class MyBinder extends Binder{ 
             //这里可以返回给Activity交互的数据
public String getTemp(){
                return "返回值";        
             }    
      }    
      @Override    
      public IBinder onBind(Intent intent) {        
             return myBinder;    
      }
}
在Activity中绑定获取数据private ServiceConnection connection=new ServiceConnection() {   @Override   public void onServiceConnected(ComponentName name, IBinder service) {
      // 这里的参数service就是交互的数据
binder=(TempService.MyBinder) service;
      ToastUtil.tostshort(LoginActivity.this,binder.getTemp());   
    }  
    @Override   
    public void onServiceDisconnected(ComponentName name) {         
    }
};

附:

1.Service的start和bind的区别?

   start启动的Service,service有独立的生命周期,不依赖启动它的组件;

   多次调用start方法,会重复调用onStartCommand方法;

   start启动的Service,必须通过stopService或者stopSelf来停止service(IntentService会自动调用stopSelf方法【上面提到过】);


   多次调用bind方法,只会调用一次onBind方法;

   bind绑定的service,service依赖于这些组件,这些组件全部销毁后,service也会随之销毁


2.同一个Service,先startService然后再bindService,怎样把它停止掉?

  无论startService被调用几次,只需stopService(或者stopSelf方法)一次就好;

  调用多次bindService,必须调用多次unbindService方法;

  因此,需要调用一次stopService(或者stopSelf方法)和多次unbindService方法,执行顺序没有要求,最后一个stopService或者unbindService方法会导致Service的onDestroy执行


3.service的onStartCommand方法的返回值,不同返回值有什么区别?

   共有四种返回值:

   START_STICKY:service被杀死后,保留启动状态,但不保存intent,之后系统会尝试重启service,并重新回调onStartCommand方法

   START_NOT_STICKY:常规操作,除非service杀死之前还有组件调用startService,否则系统不会保留启动状态并重启该Service

   START_STICKY_COMPATILITY:为了兼容版本,在service被杀死后,并不保证onStartCommand会被再一次调用

   START_REDELIVER_INTENT:service被杀死后,系统将会组织一次service重启(除非在那之前调用stopSelf()方法),被杀死前最后一次传递的Intent将重新被执行,该flag将不会传递空intent


4.Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?

   Service默认是运行在主线程的,其生命周期方法也是运行在主线程;因此如果要在Service中执行耗时操作,必须另开辟线程(或使用IntentService),否则可能会产生ANR。



   


   


原创粉丝点击