1、结论

1.通过startservice开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在
2.通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 .

2、生命周期

starterware 与 sysbios区别 startservice bindservice区别_sed


startService: onCreate -> onStartCommand -> onDestory ,在多次调用startService的时候,onCreate不重复执行,但是onStartCommand会执行。startService调用了这后,会一直存在,直到其调用了stopService。

bindService : onCreate -> onBind -> onUnbind -> onDestory,多次调用bindService,onCreate及onBind都只执行一次。它生命周期跟随其调用者,调用者释放的时候,必须对该Service解绑,当所有绑定全部取消后,系统即会销毁该服务。 bindService 的方式通过onServiceConnected方法,获取到Service对象,通过该对象可以直接操作到Service内部的方法,从而实现的Service 与调用者之间的交互。

3、使用场景

如果想要启动一个后台服务长期进行某项任务,那么使用startService
如果只是短暂的使用,那么使用bindService。
如果想启动一个后台服务长期进行任务,且这个过程中需要与调用者进行交互,那么可以两者同时使用,或者使用startService + BoardCast/ EventBus 等方法。

对于既使用startService,又使用bindService的情况,结束服务时需要注意的事项:

Service的终止,需要unbindService和stopService都调用才行;
顺便提一下IntentService,与Service的区别在于它内部封装了一个工作线程,也就是说,在其内部onHandleIntent的代码都是在子线程里面工作的。

4、示例代码

目的:使用Service播放音乐

public class PlayerServicePresenter extends BasePresenter<IPlayerServiceContract.Iview> implements IPlayerServiceContract.IPresenter{


    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
           //IOC 数据回调  和Service链接成功后 调用
            PlayerService.PlayerBinder binder = (PlayerService.PlayerBinder) service;
            playerService = binder.getService();
            playOrPaused();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //和Service链接断开后 调用
            if (playerService != null) {
                playerService.unbindService(mConnection);
                playerService = null;
            }
        }
    };
    private PlayerService playerService;

    public PlayerServicePresenter(IPlayerServiceContract.Iview view) {
        super(view);
    }


    @Override
    public void bindService(Context context) {
        if (playerService != null) {
            playOrPaused();
        } else {
            Intent intent = new Intent(context, PlayerService.class);
            context.bindService(intent, mConnection, Service.BIND_AUTO_CREATE);
        }
    }

    @Override
    public void playOrPaused() {
        if (playerService != null) {
            //开启播放音乐
            playerService.playOrPause(new RawPlayerSource().setPath(ContextHelper.getInstance().getApplicationContext().getPackageName(), R.raw.minyao),ContextHelper.getInstance().getApplicationContext());
        }
    }
}
public class PlayerService extends Service implements IPlayerListener {


    private PlayerState mState = PlayerState.IDLE;
    private IPlayer mPlayer;
    private PlayerFactory mPlayerFactory;

    @Override
    public void playerStateChanged(PlayerState state) {
        this.mState = state;
    }

    public class PlayerBinder extends Binder {

        public PlayerService getService() {
            return PlayerService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new PlayerBinder();
    }

    // onStartCommand 在 startService 有作用,start多次就会调用多次,一般用来给Serivice传递数据
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    //onCreate 不管 start 还是 bind 也不管调用几次,只会启动一次,常用来做全局初始化操作
    @Override
    public void onCreate() {
        super.onCreate();
    }

    public void playOrPause(IPlayerSource playerSource,Context mContext) {
        switch (mState) {
            case IDLE:
                //初始化播放器 去播放
                if (mPlayer != null) {
                    mPlayer.release();
                }
                if (mPlayerFactory == null) {
                    mPlayerFactory = new PlayerFactory();
                }
                if (mPlayer == null) {
                    mPlayer = mPlayerFactory.createPlayer(mContext);
                }
                if (mPlayer == null) {
                    //播放器创建失败
                    return;
                }
                //拿到播放器 去播放
                mPlayer.setPlayingListener(this);
                mPlayer.prepare(mContext,playerSource);
                break;
            case STARTED:
                //去暂停
                if (mPlayer != null) {
                    mPlayer.paused();
                }
                break;
            case PAUSED:
                //继续播放
                if (mPlayer != null) {
                    mPlayer.reStart();
                }
                break;
            case PREPARING:
                break;
               default:
                   break;
        }
    }