一、简介
Android中service(服务)运行于后台,没有界面。和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作。可以在服务中开启线程,在线程中做耗时操作。可以启动一个服务service来播放音乐,或者记录地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作。
二、Service的种类
服务一般分为两种:
1、本地服务,Local Service用于应用程序内部。
在Service可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或Service.stopSelfResult()来停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。调用startForeground()方法可以将服务运行于前台并在通知栏展示。
2、远程服务,Remote Service用于android系统内部的应用程序之间。
可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()建立连接并启动,调用Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。
三、Service的简单使用
1、startservice方法
(1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务
/**
* 创建Service的步骤:
* 1、自定义类继承系统Service
* 2、复写生命周期方法
* 3、在AndroidManifest.xml文件中通过service标签注册自定义服务
*
* 注意:Service在Application中是一全局的方式存在
*
*/
public class MyService extends Service{
/**
* 创建Service时被调用
* 此方法在一个Service的生命周期中只会别调用一次
* 一般在此方法中初始化数据
*/
@Override
public void onCreate() {
super.onCreate();
android.util.Log.e("danny", "MyService--onCreate");
}
/**
* 每次调用startService时都会调用此方法
* @param intent 就是startService时所使用的intent对象
* 根据此方法的返回值,决定所创建的Service是否是粘性服务
* START_NOT_STICKY 非粘性服务
* START_STICKY 粘性不带记忆服务
* START_REDELIVER_INTENT 粘性带记忆服务
* 一般在此方法中开启线程做耗时操作
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
android.util.Log.e("danny", "MyService--onStartCommand");
String threadName = Thread.currentThread().getName();
android.util.Log.e("danny", "threadName is " + threadName);
new Thread(){
public void run() {
for(int i = 0; i < 10; i++){
try {
Thread.sleep(1000);
android.util.Log.e("danny", "执行到 " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Intent broad = new Intent();
broad.setAction("MyBroadcas");
sendBroadcast(broad);
};
}.start();
return START_REDELIVER_INTENT;
}
/**
* 此方法跟启动服务没有任何关系,只跟绑定服务有关
*/
@Override
public IBinder onBind(Intent intent) {
android.util.Log.e("danny", "MyService--onBind");
return null;
}
/**
* 当Service被销毁时调用此方法
* Service销毁的情况;
* 1 Activity.stopService
* 2 Service.stopSelf()
*/
@Override
public void onDestroy() {
android.util.Log.e("danny", "MyService--onDestroy");
super.onDestroy();
}
}
(2)、调用startService方法启动服务;停止时调用stopService方法停止服务
case R.id.startService:
/*
* startService启动Service的步骤
* 1、创建启动服务的Intent对象,并指定目标Service
* 2、Context.startServie方法启动服务,并传递Intent对象
*
* 特点:
* 通过startService启动的服务不会跟Activity进行绑定
* 当销毁Activity时,Service不会被自动销毁
*/
Intent intent = new Intent(this, MyService.class);
startService(intent);
break;
case R.id.stopService:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); //调用Context.stopService方法停止目标Service
break;
2、bindService方法
(1)、自定义类继承系统Service,复写生命周期方法,在AndroidManifest.xml文件中通过service标签注册自定义服务
/**
* 通过bindService绑定的服务
* 生命周期:onCreate onBind onUnBind onDestroy
*
*/
public class MusicService extends Service {
/**
* 创建服务时被调用,此方法在一个生命周期中只会被调用一次
*/
@Override
public void onCreate() {
super.onCreate();
}
/**
* 当第一次调用bindService时,此方法被调用
* note:如果一个服务已经被绑定,则不会被再辞绑定
* @param intent 调用bindService时所传递的Intent对象
* @return 返回给bindService中ServiceConnection接口参数
*/
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
/**
* 当调用UNBindService解绑定一个服务时,此方法被调用
* @param intent
* @return
*/
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
/**
* 当服务被销毁时此方法被调用
*/
@Override
public void onDestroy() {
super.onDestroy();
}
private MediaPlayer player;
class MyBinder extends Binder {
/**
* 实现音乐播放的效果
*/
public void play(){
if(player == null) {
player = MediaPlayer.create(MusicService.this, R.raw.hitta);
player.start();
} else if(!player.isPlaying()) {
player.start();
}
}
/**
* 实现音乐暂停的效果
*/
public void pause() {
if(player != null && player.isPlaying()) {
player.pause();
}
}
/**
* 实现音乐停止的效果
*/
public void stop(){
if(player != null) {
player.stop();
player = null;
}
}
}
}
(2)、bindService方法绑定服务,调用unbindService方法解绑服务
public class MainActivity extends Activity {
private MyBinder mBinder;
//声明并创建绑定服务的连接回调接口
//此接口中包含了绑定服务时的回调函数
private ServiceConnection conn = new ServiceConnection() {
/**
* 当服务因异常被断开连接时调用此方法
* 参数是被绑定的服务组件名称
*/
@Override
public void onServiceDisconnected(ComponentName name) {
}
/**
* 当绑定服务连接上,并且返回具体IBinder对象时此方法被调用
* 第一个参数 绑定服务的组件名称
* 第二个参数 在绑定服务的onBind方法返回的IBinder对象
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(MainActivity.this, "服务绑定成功", Toast.LENGTH_SHORT).show();
//将Service的onBind方法中返回的IBinder对象保存
//后续可以调用此Binder中的方法
mBinder = (MyBinder) service;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* 通过bindService绑定目标Service
* 绑定服务会跟Activity进行绑定,当Activity被销毁时,此Activity所绑定的服务也会被销毁
*/
// 1 创建Intent意图,并指定目标Service
Intent intent = new Intent(this, MusicService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
public void btnClicked(View view) {
//添加判断条件,判断服务之前时候绑定成功
if(mBinder == null) {
Toast.makeText(this, "服务没有被绑定", Toast.LENGTH_SHORT).show();
return;
}
switch (view.getId()) {
case R.id.play:
mBinder.play();
break;
case R.id.pause:
mBinder.pause();
break;
case R.id.stop:
mBinder.stop();
break;
default:
break;
}
}
}