Android 四大组件之 Service

Service通常被称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面。

应用场景

  1. 不依赖于用户可视的UI界面(当然,这一条其实也不是绝对的,如一般前台Service会与Notification界面结合使用);

  2. 需要长时间运行。

Service 生命周期

1. startService调用

onCreate() ==> onStartCommand()

实际上在每次 onStartCommand 后都会调用 onStart, 但是 onStart 已经过时了,不需要考虑,也不用实现

2. bindService调用

onCreate() ==> onBind()

注意:当按返回键或主页键,或屏幕旋转,都会导致Activity被销毁,下一次Activity的onCreate会被重新调用

Activity 使用 startService(Intent) 操作 Service

1. AndroidManifest.xml 中指定 Action 对 Service 发送意图(Intent)

<service android:name=".MusicService">
    <intent-filter>
        <action android:name="com.chiyiw.music.start"/>
        <action android:name="com.chiyiw.music.next"/>
    </intent-filter>
</service>

这里指定了对 MusicService 的 start 操作和next操作

2. 给 Service 发送 action

通过发送 start 意图让 Service 执行“播放”

Intent intent = new Intent();
intent.setAction("com.chiyiw.music.start");
this.startService(intent);

通过发送 next 意图让 Service 执行“下一首”

Intent intent = new Intent();
intent.setAction("com.chiyiw.music.next");
this.startService(intent);

值得注意的是,第一次执行 startService 时,会调用 onCreateonStartCommand, 当第二次调用时,Service 的实例已经存在,不会再调用 onCreate,但会重新调用 onStartCommand

Activity 使用 bindService 操作 Service

1. Service 中自定义内部类 Binder 提供 服务获取

// Binder 继承 IBinder
class MyBinder extends Binder {
    public MusicService getService(){
        return MusicService.this;
    }
}
MyBinder binder = new MyBinder();

@Override
public IBinder onBind(Intent intent) {
    // 返回 binder
    return binder;
}

2. Activity 中实现服务连接监听

ServiceConnection connection = new ServiceConnection() {
    @Override // 连接到service时调用
    public void onServiceConnected(ComponentName name, IBinder service) {
        // 获取到 service 实例
        MusicService musicService = ((MusicService.MyBinder)service).getService();
        // ...此处可以对 service 实例执行操作
    }

    @Override // 当与service断开时执行
    public void onServiceDisconnected(ComponentName name) {
    }
};

3. Activity 中绑定Service

Intent intent = new Intent();
intent.setAction(this, MusicService.class);
this.bindService(intent, connection, Context.BIND_AUTO_CREATE);

// onDestroy 中解除绑定,否则会报“MainActivity has leaked ServiceConnection”的异常
@Override
protected void onDestroy() {
    this.unbindService(connection);
    super.onDestroy();
}

startService 与 bindService 的联系

二者可以独立使用,也可以同时使用

独立使用 startService 时,需要:

独立使用 bindService 时,需要: