BindService

269 阅读2分钟

在日常开发中,经常会遇到播放音乐的需求,比如说app退到后台时,仍然需要播放音乐。我们往往需要与Activity绑定,让其生命周期跟随版本。 bindService如何使用呢? ServiceConnection:服务链接状态的回调,并在onServiceConnected方法里面获取到IBinder对象

private class PlayServiceConnection implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        LogUtils.e("onServiceConnected"+name);
        final PlayService playService = ((PlayService.PlayBinder) service).getService();
        BaseAppHelper.get().setPlayService(playService);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        LogUtils.e("onServiceDisconnected"+name);
    }
}

开启服务:

/**
 * 开启服务
 */
private void startService() {
    Intent intent = new Intent(this, PlayService.class);
    startService(intent);
}


/**
 * 绑定服务
 * 注意对于绑定服务一定要解绑
 */
private void bindService() {
    Intent intent = new Intent();
    intent.setClass(this, PlayService.class);
    mPlayServiceConnection = new PlayServiceConnection();
    bindService(intent, mPlayServiceConnection, Context.BIND_AUTO_CREATE);
}

在Activity的onDestory方法里面进行解绑

@Override
protected void onDestroy() {
    if (mPlayServiceConnection != null) {
        unbindService(mPlayServiceConnection);
    }
    super.onDestroy();
    if(mHandler!=null){
        mHandler.removeCallbacksAndMessages(null);
        mHandler = null;
    }
}

如果我们在做音乐播放类软件时可能需要服务一直运行,所以最好在App刚打开时进行Service的开启,比如在Application中初始化一个线程池

private PoolThread executor;

 /**
 * 初始化线程池管理器
 */
private void initThreadPool() {
    // 创建一个独立的实例进行使用
    executor = PoolThread.ThreadBuilder
            .createFixed(4)
            .setPriority(Thread.MAX_PRIORITY)
            .setCallback(new LogCallback())
            .build();
}

/**
 * 获取线程池管理器对象,统一的管理器维护所有的线程池
 * @return                      executor对象
 */
public PoolThread getExecutor(){
    if(executor ==null){
        executor = PoolThread.ThreadBuilder
                .createFixed(4)
                .setPriority(Thread.MAX_PRIORITY)
                .setCallback(new LogCallback())
                .build();
    }
    return executor;
}

在GuideActivity中,先进行服务检测,如过没有可用的服务就开启一个新的服务

 /**
 * 检测服务
 */
private void startCheckService() {
    if (BaseAppHelper.get().getPlayService() == null) {
        startService();
        PoolThread executor = BaseApplication.getInstance().getExecutor();
        executor.setName("startCheckService");
        executor.setDelay(1, TimeUnit.SECONDS);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                //绑定服务
                bindService();
            }
        });
    }
}

另外,还可以写一个获取service实例的管理类

public class BaseAppHelper {

private Context mContext;
/**
 * 播放音乐service
 */
private PlayService mPlayService;

private BaseAppHelper() {}

private static class SingletonHolder {
    @SuppressLint("StaticFieldLeak")
    private final static BaseAppHelper INSTANCE = new BaseAppHelper();
}

public static BaseAppHelper get() {
    return SingletonHolder.INSTANCE;
}

public void init(Application application) {
    mContext = application.getApplicationContext();
    //这里可以做一些初始化的逻辑
}

public Context getContext() {
    return mContext;
}

/**
 * 获取PlayService对象
 * @return              返回PlayService对象
 */
public PlayService getPlayService() {
    return mPlayService;
}

/**
 * 设置PlayService服务
 */
public void setPlayService(PlayService service) {
    mPlayService = service;
	}
}

在其他页面获取service实例

/**
 * 获取到播放音乐的服务
 * @return              PlayService对象
 */
protected PlayService getPlayService() {
    PlayService playService = BaseAppHelper.get().getPlayService();
    if (playService == null) {
        //throw new NullPointerException("play service is null");
        startActivity(new Intent(getActivity(), GuideActivity.class));
        AppManager.getAppManager().finishAllActivity();
    }
    return playService;
}

参考链接:github.com/yangchong21…