android:Service介绍

本文详细介绍了Android中的Service组件,包括其概念、类型、生命周期以及启动和服务绑定的方法。Service作为四大组件之一,可在后台长时间运行,独立于Activity之外执行任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面主要讲本地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=".MyService" />
</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, MyService.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、付费专栏及课程。

余额充值