Service在Android的四大组件中,和Activity最为相似,都是从Context派生出来的,区别在于前者一直在后台运行,它没有界面。
一、Service简介
1、创建、配置Service
开发Service需要两个步骤:
(1)定义一个继承Service的子类;
(2)在manifest.xml文件中配置该Service。
例如:
配置Service和Activity很相似,甚至不用label,因为Service总是在后台,label对其没有什么意义。
<service
android:name=".MyService">
<intent-filter>
<action android:name="com.xsj.SERVICE" />
</intent-filter>
</service>
2、Service定义的系列生命周期方法:
(1)abstract IBind onBind(Intent intent):Service子类必须实现的方法,返回一个IBind对 象,应用程序可通过该对象与Service通信;
(2)onCreate():当Service第一次被创建后将立即回调该方法;
(3)onDestory():当Service被关闭之前回调该方法;
(4)onUnbind(Intent intent):当Service上绑定的所有客户端都断开连接时回调该方法;
(5)onStartCommand(Intent intent, int flags, int startId):早期为onStart()方法,每次客 户端调用startService(intent)方法启动该Service时都会回调该方法。
3、启动和停止Service
运行Service有两种方式:
(1)通过Context的startService()方法,启用Service,访问者与Service之间没有关联,如果访问者退出,Service仍然运行,对应的为stopService()关闭Service;
(2)通过Context的bindService()方法,启用Service,访问者与Service绑定在一起,如果访问者一旦退出,那么该Service也就终止了。
注:每当Service被创建时会回调onCreat()方法,每次Service被启动时会回调onStart()方法;
多次启动一个已有的Service组件将不会回调onCreate()方法,但是每次启动都会回调onStart()方法。
二、绑定本地Service并与之通信
如果Service和访问者之间需要进行方法调用或者数据交换,那么应该使用bingService()和unbindService()方法。
1、bindService(Intent service, ServiceConnection conn, int flags):
(1)service:该参数通过Intent指定要启动的Service;
(2)conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情 况,根据连接情况回调其对应的方法;
(3)flags:指定绑定时是否自动创建Service(如果Service还没有创建),0表示不自动创建, BIND_AUTO_CREATE表示自动创建。
2、通信原理
开发自己的Service时,必须提供一个IBinder onBind(intent)方法,该方法返回的IBinder对象将会传给ServiceConnection对象里的onServiceConnected()方法中的参数,这样访问者就通过该IBinder对象与Service进行通信。
实际开发中通常会采用继承Binder(IBinder的实现类)的方式来实现自己的IBinder对象。
三、项目实例
MyService是一个Service,MyActivity和它进行通信
MyService:
package com.xsj.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service {
private int count = 0;
private MyBinder binder = new MyBinder();
private boolean flag = true;
/**
* 通过继承Binder来实现IBinder
*/
public class MyBinder extends Binder {
// 这里返回了Service运行的状态,即计数值
public int getCount() {
return count;
}
}
/**
* 必须实现的方法,这里返回了IBinder对象
*/
@Override
public IBinder onBind(Intent intent) {
return binder;
}
/**
* Service被创建时回调该方法
*/
@Override
public void onCreate() {
showCount();
}
/**
* Service被断开连接时回调的方法
*/
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
/**
* Service被关闭之前回调的方法
*/
@Override
public void onDestroy() {
flag = false;
super.onDestroy();
}
/**
* 计数操作
*/
private void showCount() {
new Thread() {
@Override
public void run() {
while (flag) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
}.start();
}
}
MyActivity:
package com.xsj.service;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MyActivity extends Activity {
private Button start;
private Button stop;
private Button getCount;
MyService.MyBinder binder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
getCount = (Button) findViewById(R.id.get_count);
final Intent intent = new Intent();
intent.setAction("com.xsj.SERVICE");
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 绑定指定的service
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 在这里解除和service的绑定
unbindService(conn);
}
});
getCount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MyActivity.this,
"来自service - " + binder.getCount(), Toast.LENGTH_LONG)
.show();
}
});
}
/**
* ServiceConnection对象
*/
private ServiceConnection conn = new ServiceConnection() {
// 当activity和service断开连接时回调该方法
@Override
public void onServiceDisconnected(ComponentName name) {
}
// 当activity和service连接成功时回调该方法
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获取service的onBind()方法所返回的MyBinder对象
binder = (MyService.MyBinder) service;
}
};
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
运行时,点击开始按钮,启动Service,count开始增加,点击获取数据按钮,返回count的当前值,点击停止按钮,解除绑定。
注:与采用startService()启动Service所不同的是,多次调用bindService()方法并不会执行重复绑定,即无论点击多少次开始按钮,系统只会回调Service的onBind()方法一次。