简介

Service作为Android的四大组件之一,它的重要性不言而喻,之前虽说看过一些介绍但是一直没有用过,最近需要用到的时候发现无从下手,便阅读了官方的有关Service的Guide,这里总结一下。

Service作用

官方介绍如下

A Service is an application component representing either an application’s desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.

Service主要用于在后台执行长期任务或者耗时操作,在需要的时候甚至可以在应用退出的时候保持运行状态。

Service与Thread

虽说Service可以在后台执行任务,但是实际上一个Service是运行在主线程的,如果有耗时操作我们必须在Service中自己开启一个Thread避免ANR。那就会有这么一个问题,我们为什么不用Thread呢?主要的原因就是Thread的可控性不好,假设我们在一个Activity中启动了一个Thread,一旦这个Activity结束了,那么其他的Activity就没有办法拿到这个Thread的引用,更别谈控制了。可是Service不一样,一个Service整个程序只会创建一个实例,而且任何Activity都可以控制,那么Service里的Thread就可以由所有Activity控制了。而且Service作为四大组件之一,有较高级别,在后台运行不容易被系统杀掉。

Service分类

Service分为两类

  • Started Service:不和其他组件通信
  • Bound Service:可以和其他组件通信

    无论使用哪一种Service都必须重写onBind()方法,如果使用Started Service返回null就可以了。

使用Started Service

一般需要再重写两个方法

  • onCreate():启动Service的时候并不存在该Service实例,就会调用该方法。
  • onStartCommand(Intent intent, int flags, int startId):每次通过startService(Intent intent)启动的时候就会掉用该方法,一般在这里开启新线程。

onStartCommand(Intent intent, int flags, int startId)方法返回int类型的值,代表Service被kill后的行为,有以下三种:

  • START_NOT_STICKY:表示不重新创建
  • START_STICKY:表示重新创建,调用onStartCommand传入null
  • START_REDELIVER_INTENT:表示重建,调用onStartCommand传入上一个Intent

为了节省资源和电量,我们在任务结束后必须关闭Service,想要关闭Service可以通过本身调用stopSelf()或者其他组件调用stopService(),但是如果我们的Service处理多个onStartCommand请求的时候,我们在请求结束后掉用stopSelf()可能会打断已经收到的新的请求,最好的情况就是我们本身就是最后一个请求,stopSelt(int)的一个参数的重载可以解决这个方法,传入的id就是onStartCommand传递进来的id,代表当前任务的id,它会把传入的id和最后一个id比较,如果一样的话就代表本身是最后一个任务,就会stop掉,否则不会执行stop。

使用Bound Service

主要和Started Service的区别就是可以和其他组件通信,通过Binder。
创建时必须定义接口描述用户如何与Server交流,接口必须继承Binder。使用bindService()创建,必须提供一个ServiceConnection的实现,,bindService()是一个异步方法,立马回返回。当创建完后会调用ServiceConnection的onServiceConnected,并传递binder通信。onBind方法只在第一个用户连接调用,后来都返回同一个binder(因为只会有一个Service),代码如下

public class LocalService extends Service {    // Binder given to clients    private final IBinder mBinder = new LocalBinder();    // Random number generator    private final Random mGenerator = new Random();    /**     * Class used for the client Binder.  Because we know this service always     * runs in the same process as its clients, we don't need to deal with IPC.     */    public class LocalBinder extends Binder {        LocalService getService() {            // Return this instance of LocalService so clients can call public methods            return LocalService.this;        }    }    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    /** method for clients */    public int getRandomNumber() {      return mGenerator.nextInt(100);    }

bind service的代码如下

private ServiceConnection mConnection = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName className,                IBinder service) {            // We've bound to LocalService, cast the IBinder and get LocalService instance            LocalBinder binder = (LocalBinder) service;            mService = binder.getService();            mBound = true;        }        @Override        public void onServiceDisconnected(ComponentName arg0) {            mBound = false;        }    };
bindService(intent, mConnection, 0);

可以看出我们在Service中自定义了binder继承自Binder,并声明了一个方法,然后在onBind()中返回一个实例。我们会在onServiceConnected方法中得到这个binder,然后我们调用里的方法得到Service的实例,这样就可以掉用里面方法了,也就完成了通信。bindServicer第三个参数是刚开始的选择,如果是BIND_AUTO_CREATE表示如果没启动就新建

注意事项

onServiceDisconnected方法不是unbind的时候调用的,实在被kill等意外情况调用的

更多相关文章

  1. Android之路——第一个Android小程序(Android电话拨号器)
  2. Android(安卓)点击事件分发
  3. Android(安卓)Handler 通信 - 彻底了解 Handler 的通信过程
  4. Android新线程中更新主线程UI中的View方法汇总
  5. Java super关键字(android中常见)
  6. Android(安卓)OpenGL ES 分析与实践
  7. android的生命周期
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android(安卓)访问权限许可大全
  2. Android(安卓)O u-blox gps移植
  3. Android-- 输入法键盘控制
  4. Android(安卓)播放音乐的service
  5. Android(安卓)倒计时控件
  6. httplive流媒体播放(m3u8)
  7. [置顶] android中横竖屏幕的处理
  8. Android读程序包的资源
  9. 收集android的三个小tip
  10. android获取经纬度和地方名称(baidu api)