服务Service是四大组件之一,
特点:1 没有界面 2 在后台一直运行 3 只有一个实例
服务运行在主线程,所以不能在服务里做耗时的操作,可以在服务里开启子线程
有两种启动服务的方式
1、context.startService(); 只能stopService()才能停止
生命周期
onCreate() (一次)
onStart() (多次,在同一个activity里可多次onStart)
onDestroy()
2、context.bindService(); 只能通过unbindService()才能停止
生命周期
onCreate() (一次)
onBind() (多次,这里指如果有更过activity,还可以绑定)
on Unbind()
on Destory()
创建步骤
写一个类继承Service 然后在清单文件注册 <service android:name=".MyService"></service>
startService()方法里需要传入一个intent,Intent把服务和activity联系起来
Intent service = new Intent(this,MyService.class);
startService(service);
而bindService(service, conn, Context.BIND_AUTO_CREATE);中间参数需要一个ServiceConnection的实例,所以定义一个类实现它
两种启动方式的 区别:
context.startService(); 访问者和服务之间是没有关联关系的。
访问者不能和服务进行通讯(不能调用服务里面的方法)
在一个activity里创建的服务,另外一个activity能停止服务
context.bindService(); 只有访问者才能去停止服务。
访问者能和服务进行通讯,访问者和服务同生共死
在一个activity里绑定的服务,只能通过这个activity去解绑服务
像在音乐播放器里,需要用到bindService的方式,因为想暂停音乐只能通过bind的形式暂停,也就是start方式访问者不能和服务进行通讯,bind方式访问者能和服务进行通讯
在MainActivity里
public class MainActivity extends Activity {
private Intent service;
private MyServiceConnection conn = new MyServiceConnection();
private IMusic imusic;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
service = new Intent(this, MyService.class);
}
public void start(View v){
bindService(service, conn, Context.BIND_AUTO_CREATE);//服务自动创建
}
public void pause(View v){
//暂停
imusic.pause();
}
public void moveon(View v){
//继续
imusic.moveon();
}
public void stop(View v){
unbindService(conn);
}
//连接对象
private class MyServiceConnection implements ServiceConnection{
//服务连接是调用
public void onServiceConnected(ComponentName name, IBinder service) {
imusic = (IMusic) service;
}
public void onServiceDisconnected(ComponentName name) {
}
}
}
在MyService类里
public class MyService extends Service {
private MediaPlayer mp;
@Override
public void onCreate() {
super.onCreate();
try {
mp = new MediaPlayer();
//置为初始化状态
mp.reset();
//设置播放内容
File file = new File(Environment.getExternalStorageDirectory(), "Baby.mp3");
mp.setDataSource(file.getAbsolutePath());
//准备
mp.prepare();
//播放
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private MyBinder ibinder = new MyBinder();
//返回IBinder IBinder是一个接口,他是用来实现进程间通信的。
@Override
public IBinder onBind(Intent intent) {
return ibinder;
}
@Override
public void onDestroy() {
super.onDestroy();
//停止
mp.stop();
//释放资源
mp.release();
mp = null;
}
//Binder底层已经实现了IBinder
public class MyBinder extends Binder implements IMusic{
public void pause() {
mp.pause();//暂停
}
public void moveon() {
mp.start();//继续
}}
}
在IMusic接口里
public interface IMusic {
public void pause();
public void moveon();
}
步骤
首先在MainActivity里点击start按钮,开始bindService,接着调用MyService里的onBind方法,这时onBind返回IBinder对象,而IBinder是一个接口,由于Binder底层实现了IBinder,所以这里继承Binder,同时定义一个接口IMusic,实现它,这个接口提供两个方法。为什么要定义接口呢?因为MediaPlayer在MyService里,而点击事件在MainActivity里,想通过MainActivity的点击事件控制MyService里的MediaPlayer,需要通过这个IMusic提供的两个方法来控制。前面返回Binder对象之后,说明MainActivity
和MyService连接了,就会调用onServiceConnected方法,在这个方法里可以实例化IMusic,然后在MainActivity的点击事件里调用IMusic的方法,就会调用MyBinder里实现
IMusic接口的方法,在里面就可以进行MediaPlayer操作了