Service是Android系统提供的四种组件之一,顾名思义Service就是运行在后台的一种服务程序,一般很少和用户交互,因此没有可视化界面。定义一个Service类比较简单,只要继承Service类,实现其生命周期中的方法就可以了。一个定义好的Service必须在AndroidManifest.xml配置文件中通过<Service>元素声明才能使用。Service中定义了一系列和自身生命周期相关的方法,这些方法有:
- onBind(Intent intent):是必须实现的一个方法,返回一个绑定的接口给Service。
- onCreate():当Service第一次创建时,由系统调用。
- onStart(Intent intent,int startId):当通过startService()方法启动Service时,该方法被调用。
- onDestory():当Service不再使用,系统调用该方法。
1、启动和停止Service
一旦定义好一个Service就可以在其他组件中启动该Service来使用它了。启动一个Service使用Context.startService(Intent intent)方法,这和启动一个Activity非常相似,也是传递一个Intent。当我们调用startService()方法时,被调用的Service会调用它的onCreate()方法(如果该Service还没有创建),接着调用onStart()方法。一旦Service启动后将一直运行到调用了Context.stopService()或者stopSelf()才停止。
//在其他组件里启动Service
//创建Intent
Intent intent = new Intent();
//设置Action属性
intent.setAction("com.igood.test.MY_SERVICE");
//启动一个Service
startService(intent);
//停止一个Service
stopService(intent);
要想使用该Service必须在AndroidManifest.xml配置文件中使用<service>元素声明该Service。在<service>元素中添加<intent-filter>指定如何访问该Service。
<service android:name="MyService">
<intent-filter>
<action android:name="com.igood.test.MY_SERVICE"/>
</intent-filter>
</service>
2、绑定和解除绑定Service
除了可以调用startService()方法来启动一个Service方法,我们也可以通过bindService()方法来绑定一个Service。bindService()方法会调用onCreate()方法来创建Service(如果它未创建),但是它不会调用onStart()方法而是调用onBind()返回客户端一个IBinder接口。绑定Service一般是用在远程Service调用。
绑定Service需要三个参数:bindService(intent,conn,Service.BIND_AUTO_CREATE);第一个是Intent;dierge
//创建Intent
Intent intent = new Intent();
//设置Action属性
intent.setAction("com.igood.test.MY_SERVICE");
//连接对象
ServiceConnection conn = new ServiceConnection() {
@Override//连接时调用
public void onServiceDisconnected(ComponentName name) {
Log.i("SERVICE","连接成功");
}
@Override//断开时调用
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("SERVICE","断开连接");
}
};
//绑定Service
bindService(intent, conn, Service.BIND_AUTO_CREATE);
3、Service的生命周期
下面通过一个实例来演示如何创建、启动、停止及绑定一个Service。我们在MainActivity中声明四个Button对象,分别用来启动Service、停止Service、绑定Service和解除绑定Service。
//MainActivity.java
public class MainActivity extends Activity {
private Button btnStart;
private Button btnStop;
private Button btnBind;
private Button btnUnbind;
private ServiceConnection conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置Activity的界面布局
setContentView(R.layout.main);
//通过findViewById方法获得Button实例
btnStart = (Button)findViewById(R.id.btnstart);
btnStop = (Button)findViewById(R.id.btnstop);
btnBind = (Button)findViewById(R.id.btnbind);
btnUnbind = (Button)findViewById(R.id.btnunbind);
//添加监听器
btnStart.setOnClickListener(startListener);
btnStop.setOnClickListener(stopListener);
btnBind.setOnClickListener(bindListener);
btnUnbind.setOnClickListener(unbindListener);
//连接对象
conn = new ServiceConnection() {
@Override//连接时调用
public void onServiceDisconnected(ComponentName name) {
Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_LONG).show();
}
@Override//断开时调用
public void onServiceConnected(ComponentName name, IBinder service) {
Toast.makeText(MainActivity.this, "断开连接", Toast.LENGTH_LONG).show();
}
};
}
private OnClickListener startListener = new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.igood.test.MY_SERVICE");
//启动Service
startService(intent);
}
};
private OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.igood.test.MY_SERVICE");
//停止Service
stopService(intent);
}
};
private OnClickListener bindListener = new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.igood.test.MY_SERVICE");
//绑定Service
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
};
private OnClickListener unbindListener = new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("com.igood.test.MY_SERVICE");
//解除绑定Service
unbindService(conn);
}
};
}
//MyService.java
public class MyService extends Service {
//当客户端调用bindService()方法启动Service时,该方法被调用
@Override
public IBinder onBind(Intent intent) {
Log.i("SERVICE", "onBind......................");
Toast.makeText(MyService.this, "onBind......................", Toast.LENGTH_LONG).show();
//可以返回null,通常返回一个有aidl定义的接口
return null;
}
//Service创建时调用
@Override
public void onCreate() {
super.onCreate();
Log.i("SERVICE", "onCreate......................");
Toast.makeText(MyService.this, "onCreate......................", Toast.LENGTH_LONG).show();
}
//当客户端调用startService()方法启动Service时,该方法被调用
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i("SERVICE", "onStart......................");
Toast.makeText(MyService.this, "onStart......................", Toast.LENGTH_LONG).show();
}
//当客户端调用unbindService()方法启动Service时,该方法被调用
@Override
public boolean onUnbind(Intent intent) {
Log.i("SERVICE", "onUnbind......................");
Toast.makeText(MyService.this, "onUnbind......................", Toast.LENGTH_LONG).show();
return super.onUnbind(intent);
}
//当Service不再使用时,该方法被调用
@Override
public void onDestroy() {
super.onDestroy();
Log.i("SERVICE", "onDestroy......................");
Toast.makeText(MyService.this, "onDestroy......................", Toast.LENGTH_LONG).show();
}
}
Manifest.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=".MyService">
<intent-filter>
<action android:name="com.igood.test.MY_SERVICE"/>
</intent-filter>
</service>
</application>
运行结果:
1、点击startService按钮,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()
方法并不会导致多次创建服务,但会导致多次调用onStart()方法,运行效果如下:
2、采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,此时,接着点击stopService按钮,服务结束时会调用onDestroy()方法,多次点击stopService按钮也只调用一个onDestory()方法。运行效果如下:
3、重新运行程序,点击bindService按钮,调用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起。如果此时多次点击bindService按钮,多次调用bindService()方法前服务已经被绑定,并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。运行效果如下:
4、此时,点击unbindService按钮,调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()和onDestroy()方法,进行对Service的解除绑定,运行效果如下: