首页 > 系统 > Android > 正文

Android Service

2019-11-08 00:27:39
字体:
来源:转载
供稿:网友

 在Android组件中,service一是用于在后台处理一些不需要user看到的事件,比如有一些只有在AP启动的时候才听的action,可以动态的在service里来监听,动态注册receiver,还有一些需要receiver来驱动的事件,由于receiver不适合处理复杂耗时的逻辑,可以start service来做UI显示前的处理,在需要和适合显示的时候才发消息给UI 来显示。再一个就是返回bind接口供AP 来调用需要的API 。那么首先第一个问题,怎么启动一个service呢?

        启动一个service有两种方式,context.startService() and context.bindService(),下面就分别介绍一下。

        1.  Start service.

[java] view plain copy<span style="font-size:18px;">  PRivate void startSimpleService() {          Log.d(TAG, "startSimpleService ****");          Intent service = new Intent(this, MySimpleService.class);          this.startService(service);      }</span>          调用startService后会做些什么呢?首先如果service还没有create,系统会调用service的onCreate(),然后onStartCommand(),这个时候service处于foreground状态,具有比较高的优先级,不会被系统kill掉。在2.0之前的版本里会用到onStart()这个api,但是之后的版本里这个api就被弃用了,因为android是系统来管理内存的,在系统内存紧张的时候会根据优先级kill掉一些优先级比较低的进程,而service在start后就不再是foreground状态,优先级就会降低,这个时候就容易被系统kill掉,而在2.0之前的版本,service在被系统kill掉之后,在系统内存不紧张的时候被restart,这个时候service的onCreate被调用,但是onStart并不会被调用,因为没有startService,这个时候就会比较尴尬,service create了,但是却没事做,也不知道什么时候stop。因此在2.0之后的版本里使用了onStartCommand()

[java] view plain copy<span style="font-size:18px;">  @Override      public int onStartCommand(Intent intent, int flags, int startId) {          // TODO Auto-generated method stub          Log.d(TAG, "onStartCommand =====");          return Service.START_STICKY;      }</span>  不同的地方是,它可以return一个int值,START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT.

START_STICKY: 和原来的onStart类似,在被系统kill掉后会restart,但是不同的是onStartCommand会被调用并传入一个null值作为intent,这个时候service就可以对这种case做出处理。

START_NOT_STICKY: 被kill掉后就不会自动restart了。

START_REDELIVER_INTENT: 如果service被kill掉了,系统会把之前的intent再次发送给service,直到service处里完成。

    还有一点就是setforeground()这样的api也被弃用了,foreground状态是具有比较高的优先级的,有些开发者为了避免自己的service由于优先级太低被系统kill掉,就一直让自己的service跑在foreground状态,这显然是不合适的,这样系统的自动回收机制就被废掉了,大量的service占用了资源却不能被kill掉。在后来的版本里foreground的要有一个notification通知User,有一个service在foreground状态。

    最后,start的service必需在不需要的时候主动stop掉,避免占用太多资源。

    2. bind service

可以得到从service返回的bind接口,从而可以调用接口中的api。如果service没有create,在第一个process bind上来的时候会create,在最后一个process unbind后会destroy掉,因此,在使用完后要及时的unbind,避免占用资源。和start不同,bind的时候会调用service的onBind接口。

//MySimpleService

[java] view plain copypublic class MyBinder extends Binder {            public String getString() {          return "simple test";      }  }    private final MyBinder myBinder = new MyBinder();  @Override  public IBinder onBind(Intent arg0) {      // TODO Auto-generated method stub      Log.d(TAG, "onBind =====");      return myBinder;  }  

//MainActivity

[java] view plain copyMyBinder mBinder = null;  private ServiceConnection simpleConn = new ServiceConnection() {        @Override      public void onServiceConnected(ComponentName name, IBinder service) {          // TODO Auto-generated method stub          Log.d(TAG, "onServiceConnected ***");          mBinder = (MyBinder)service;          Log.d(TAG, mBinder.getString() + "****");      }        @Override      public void onServiceDisconnected(ComponentName name) {          // TODO Auto-generated method stub          Log.d(TAG, "onServiceDisconnected ***");      }        };    private void bindSimpleService() {      Intent service = new Intent(this, MySimpleService.class);      this.bindService(service, simpleConn, Service.BIND_AUTO_CREATE);  }    private void unbindSimpleService() {      this.unbindService(simpleConn);  }  

    最后需要说明一点,service不是一个子线程,如果有耗时的操作应该放到子线程里处理,如果service长时间被block,会有ANR的情况。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表