在日常开发中,经常会遇到播放音乐的需求,比如说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;
}