android:Service介绍

下面主要讲本地Service:
什么是Service:
Service 是android系统四大组件之一, Service主要有两个作用:
  1. 长驻后台,运行一些任务(例如:1. 你需要在后台每隔一段时间就执行某个任务,即使activity退出了)
  2. Service可以被跨进程访问

注意
  1. Service不是一个单独的进程,它和应用程序共享同一个进程。
  2. Service不是一个线程,它运行在应用程序的主线程(所以你要进行耗时操作的话,可以在service里另开一个线程,否则会阻塞主线程)
这里可能你会问一个问题:如果Service和应用程序运行在同一个主线程,那么为什么Activity退出后Service还在运行呢?
这是因为Service和activity运行在同一个线程中,退出activity,但因为service还在,所以它所在的线程其实还是存在的。activity被销毁,只不过是这个activity所占用的资源被释放掉了,这个activity所在的主线程只有但android内存不足才会被杀掉,否则一般情况下activity所在的应用程序的线程始终存在,这也是这个activity所启动的服务会一直运行下去的原因。

Service和Thread的区别:
(总结一下下面这段话:就是Service可以一直在后台运行(不管activity退没退出),更方便于被各应用程序控制和管理)
Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以进行一些耗时的操作。
Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 Service 是运行在主进程的 main 线程上的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。
既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿 Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。

Service根据它启动方式的不同可以分为两种:启动型Service(无限生命)、绑定型Service(有限生命)。

  1. 启动型Service(无限生命)
如果一个Service被某个Activity 调用 Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。
如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。
当启动型Service被绑定:
如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
  1. 绑定型Service(有限生命)
如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用 bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService 断开连接或者之前调用bindService 的 Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。
注意:
1、同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
2、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
3、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。

一个Service例子:
在Manifest中注册:
< application   . . . . . . >
        < activity . . . . . . >
        < service android:name = ". My Service" />
</ application >
public class MyService extends Service {
     private MyBinder myBinder = new MyBinder();
     @Override
     public void onCreate() {
        // 只会在初次创建时调用一次
        super .onCreate();
    }
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
        // 只有启动型Service会调用这个方法,startService方法可以被多次启动,同时此方法也会被多次调用
        // 可以把启动型Service要做的任务写在这里,任务相关数据可以有intent传进来
        return super .onStartCommand(intent, flags, startId);
    }
    
     @Override
     public IBinder onBind(Intent arg0) {
        // 在Service被绑定时会调用
        // 如果是绑定型Service,可以把相关数据通过Intent传进来
        // return null;// 如果你是使用启动型Service,则返回null就可以了
        return myBinder ;
    }
    
     @Override
     public boolean onUnbind(Intent intent) {
        // 断开绑定
        // 如果是绑定型Service,断开绑定/context连接消失/activity退出,都会使Service结束
        // 如果是启动型Service,断开绑定,Service不会结束;断开绑定并且stopService服务才会结束
        return super .onUnbind(intent);
    }
     @Override
     public void onDestroy() {
        // Service 结束,你可以在这里结束你创建的Thread或者一些变量
        super .onDestroy();
    }
    
     class MyBinder extends Binder {
        // 创建一个方法,返回本Service,这样前台就可以获得本Service实例,进行交互了
        public MyService getService() {
            return MyService. this ;
       }
    }
}
启动此Service的几种方法:
  1. 启动型启动:
Intent intent= new Intent(MainActivity. this , My Service. class );
startService(intent);
stopService(intent); //停止此service,intent不一定要用同一个实例
如果启动了Service后,需要绑定Service也可以,方法如下:
  1. 绑定型启动
  public class MainActivity extends Activity {
     private Button btn _ StartService ;
     private Button btn _ StopService ;
     private BinderService myService ;
     private Boolean isConnected = false ;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
        super .onCreate(savedInstanceState);
       setContentView(R.layout. activity_main );
        btn _ StartService = (Button) findViewById(R.id. btnStartService );
        btn _ StopService = (Button) findViewById(R.id. btnStopService );
        btn _ StartService .setOnClickListener( listener );
        btn _ StopService .setOnClickListener( listener );
    }
     private OnClickListener listener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id. btnStartService :
              Intent intent = new Intent(MainActivity. this , BinderService. class );
               // 绑定Service需要一个连接
              bindService(intent, conn , Context. BIND_AUTO_CREATE );
               break ;
            case R.id. btnStopService :
               if ( isConnected ) {
                  unbindService( conn );
              }
               break ;
            default :
               break ;
           }
       }
    };
     private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            // 这里的参数binder就是Service的onBind()方法传进来的
            // 这样就可以在这里获取到Service的实例,然后与Service进行交互
           MyBinder myBinder = (MyBinder) binder;
            myService = myBinder.getService();
            isConnected = true ;
       }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            isConnected = false ;
       }
    };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值