Class Overview
1.Service是Android的四大应用组件之一,主要用于实现一些不需要与用户交互的操作,如较长时间执行某一任务。Service提供的功能可以被其它应用使用,具体可以通过设置android:exported=false(true)属性来控制其是否能被其它应用使用。
每个Service必须在AndroidManifest.xml中申明,在应用中可通过Context.startService()和Context.bindService()来启动。startService(Intent service); //发送Intent过去,启动service
bindService(Intent service, ServiceConnection conn, int flags); //注意serviceConnection,会返回IBinder对象,该对象是services的onBind()方法返回的,使得client能够回调services中的方法。
该方法启动service不会调用onStartCommand()。
2. Service和其它应用程序对象一样,运行于主线程,也就是说如果要执行耗时操作,必须开启一个线程来做。IntentService是Service的一个标准实现,它包含一个线程,负责执行任务,任务执行完后会自动stop。
从Service的特性可以得出,Service不是一个独立的进程,也不是一个线程。它运行于主线程,如果要执行耗时操作必须创建一个线程来做。
3. 重写Service类必须实现onBinder()方法。
4. Service有2中执行模式,通过onStartCommand()返回值设定(START_STICKY, START_NOT_STICKY/START_REDELIVER_INTENT)
5. Context.bindService()启动Service使client和Service处于连接状态(client端保持service端的IBinder引用),当连接断开service才会停止。
6. android:process=”XXXX”,service运行的进程名,一般应用程序运行于创建它的进程,进程名即为应用包名。如果设置service进程名的该属性以”:”开头,则表示service将运行在一个新的进程,如果进程名为小写,则该进程为全局进程,在其它应用程序中的组件也可以共享该进程,减少资源使用。
7. 可以通过startForeground(int, Notification)将service设为前台状态。
Example:
1. 本地Service实现MyLocalService.java
<span style="font-family:Arial;font-size:14px;">public class MyLocalService extends Service{
private static final String TAG = "MyLocalService";
private final IBinder mBinder = new LocalBinder();
public void onCreate(){
Log.d(TAG,"onCreate");
}
/**
* return modes of operation services run in
* START_STICKY services are explicitly start and stop
* START_NOT_STICKY,START_REDELIVER_INTENT services will keep running while processing any commands
*/
public int onStartCommand(Intent intent, int flags, int startId){
return START_STICKY;
}
public void onDestory(){
}
public IBinder onBind(Intent intent){
return mBinder;
}
/**
* Class for client to access. Owing to this service always
* running in the same process as its clients. We don't need to
* deal with IPC
*/
public class LocalBinder extends Binder {
MyLocalService getService(){
return MyLocalService.this;
}
}
}</span>
Client调用bindService()与service建立连接。
<span style="font-family:Arial;font-size:14px;">public class MainActivity extends ActionBarActivity {
private MyLocalService mLocalService;
private boolean isBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
doBindService();
}
@Override
protected void onDestroy(){
super.onDestroy();
doUnBindService();
}
private ServiceConnection mConnection = new ServiceConnection(){
/*
* This is called when the connection with service has been
* established, giving us the service object we can to interact with
* the service. Because we have bound to a explicit service that is running
* in our process, we can cast its IBinder to an concrete class and
* directly access it.
*/
public void onServiceConnected(ComponentName className, IBinder service){
mLocalService = ((MyLocalService.LocalBinder)service).getService();
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
mLocalService = null;
}
};
/*
* establish a connection with the service
*/
public void doBindService(){
bindService(new Intent(MainActivity.this,MyLocalService.class),mConnection,Context.BIND_AUTO_CREATE);
isBound = true;
}
public void doUnBindService(){
if(isBound){
unbindService(mConnection);
isBound = false;
}
}
}</span>
根据上面的代码,可以看到Client通过调用bindService()来绑定service,该API接口的ServiceConnection会在ServiceConnection对象创建时确定。在绑定service后Client端会得到IBinder对象,该对象就是Service的onBind()返回的Binder对象。通过这个IBinder对象我们可以远程调用service。
2. Remote Service实现MyRemoteService.java<span style="font-family:Arial;font-size:14px;">public class MyRemoteService extends Service {
private static final String TAG = "MyRemoteService";
public void onCreate(){
Log.d(TAG,"onCreate");
}
public void onDestory(){
Log.d(TAG,"onDestory");
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return serviceBinder;
}
IMyAIDLTest.Stub serviceBinder = new IMyAIDLTest.Stub() {
@Override
public int sayHello() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
};
}</span>
从上面的代码可以看到,onBinder()返回的是AIDL中定义的接口的stub对象,该stub对象是继承了IBinder