服务(Service)是Android实现后台运行的解决方案,它适用于执行哪些不需要和用户打交道而且还要长期运行的任务。服务的运行部依赖于任何用户界面,即使当程序切换到后台,或者打开另一个应用程序,服务仍然能够保持运行。
不过需要注意的是,服务并不是运行在一个独立的进程中,而是依赖于创建服务时所在的应用程序进程。如果应用程序进程被杀掉,所依赖于该进程的服务也会被停止运行。
一、定义一个服务
创建一个类MyService继承自Service
public class MyService extends Service{
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
}
onBind()方法是Service中唯一的抽象方法,所以必须在子类里实现,onCreate()方法是服务第一次创建的时候调用的,onStartCommand()方法是每次服务启动的时候调用,可以把服务一启动的逻辑在写在这里,
onDestroy()方法是服务销毁的时候调用的。另外要注意的是,每个服务都需要在AndroidManifest.xml中注册,
这是四大组件共同的特点。修改AndroidManifest.xml:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.gomez.servicedemo.MyService"
></service>
</application>
二、服务的启动和停止
我们在Mainactivity中定义两个Button来分别启动服务和停止服务,代码如下:
<span style="white-space:pre"> </span>case R.id.btn_start:
intent1 = new Intent(MainActivity.this, MyStartService.class);
startService(intent1);
break;
case R.id.btn_stop:
stopService(intent1);
break;
我们先构建一个Intent对象,然后分别调用startService()和stopService()来启动服务和停止服务。startService()和stopService()都是定义在Context类中的,所以我们可以在活动里直接调用。但是,这都是由活动来决定服务的启动和停止,如果想在服务中停止服务,那么只需在程序任何的位置调用stopSelf()就可以了。
三、活动和服务进行通信
活动想跟服务进行通信,就需要借助我们忽略的onBind()方法了,修改MyService的代码:
public class MyService extends Service{
public class MyBinder extends Binder{
public MyBindService getService(){
return MyService.this;
}
public void getProgress() {
Log.i("MyBindService", "getProgress excuted");
}
}
//当执行bindService()就会调用
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i("info", "BindService--onBind()");
return new MyBinder();
}
这里新建一个MyBinder类,并让它继承自Binder,然后在它的内部提供了一个返回自己对象的方法和一个打印信息的方法,然后在onBind()方法返回了MyBinder这个实例。
接下来我们再新建两个按钮分别用于活动进行绑定服务和解绑服务。
public class MainActivity extends Activity {
private Intent intent1;
private Intent intent2;
private MyService myService;
private ServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void doClick(View v){
switch (v.getId()) {
case R.id.btn_start:
intent1 = new Intent(MainActivity.this, MyStartService.class);
startService(intent1);
break;
case R.id.btn_stop:
stopService(intent1);
break;
case R.id.btn_bind:
Log.i("tag", "msg");
intent2 = new Intent(MainActivity.this, MyService.class);
//startService(intent2);
conn = new ServiceConnection() {
@Override//当我们的启动源跟service的连接意外丢失的时候会调用
//比如当Service崩溃了或者被强行杀死
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override//当启动源跟Service成功连接之后将会自动调用
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
myService = ((MyService.MyBinder)service).getService();
}
};
bindService(intent2, conn, BIND_AUTO_CREATE);//绑定服务
break;
case R.id.btn_unbind:
unbindService(conn);//解绑服务
break;
这里我们新建了一个ServiceConnection的匿名类,里面重写了onServiceConnected()和onServiceDisconnected()方法,这两个方法分别在活动绑定和解绑服务的时候调用,在onServiceConnected()方法中,第二个参数IBinder对象就是onBind()返回的IIBinder实例,我们向下转型得到了MyService对象,有了这个实例,活动跟服务就已经紧密地联系起来了,活动可以指挥服务执行哪些操作。然后我们还要绑定这个服务,调用bindService()方法进行绑定,第一个参数是刚刚构建的Intent对象,第二个参数是创建的ServiceConnection是咧,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在活动和服务绑定后自动创建服务
四、服务的生命周期
在活动中调用了Context的startService()方法,相应的服务就会启动起来,并回调onStartCommand()方法,如果这个服务之前还没有创建过,onCreate()方法会先于onStartCommand()方法执行。启动服务之后会一直被保持运行的状态,直到stopService()或stopSelf()方法被调用。虽然每调用一次startService()方法,onStartCommand()都会执行一次,但是Service的实例只被创建了一次,实际上每个服务都只会有一个实例,因此不管你调用了几次startService(),只需调用一次stopService()或stopSelf()方法,服务就会停止下来。
另外,还可以调用Context的bindService()方法来获取一个服务的持久连接,这是就会回调服务中的onBind(),同样,如果这个服务之前还没有创建过,onCreate()会先于onBind()方法执行。只要没有调用unbindService()方法,服务就会一直运行。
当只调用startService()和bindService()的二者之一,分别调用相应的stopService()(或stopSelf())方法和unbindService()方法,服务就会停止下来。当startService()和startService()二者都调用了,停止服务就要同时调用stopService()和unbindService()方法,onDestroy()方法才会执行。