Service作为Android的四大组件之一。主要是用在后台执行长时间的操作,Service没有UI界面。非常适合用于去执行哪些不需要和用户交互而且还要求长期运行的任务。
启动一个Service主要有两种方式,一个是startService(),一个是通过bindService()。
1、在应用的任何一个地方,通过调用startService()方法就可以启动一个Service了。
然后Service类的onCrete() onStartCommand()和onStart()方法就会依次被调用,这样子对应的service就被启动起来了。
通过这样子启动起来的service不会主动退出,需要应用主动的调用stopSercive()去做退出动作。
如果还有其他应用也要启动相同的service,是不会执行onCreate()方法,直接执行onStartcommand()和onStart()方法。
这样子启动service不会调用对应的onBind()和onUnbind()方法
1.1 在AndroidManifest.xml 增加一个Service
<service android:name="com.android.service.demo.BGService" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="com.android.service.BGSERVICE_START" />
</intent-filter>
</service>
1.2 实现一个没有任何实质内容的service,只添加对应的log信息
package com.android.service.demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class BGService extends Service {
private final String TAG = "BGService";
public static final String ACTION = "com.android.service.BGSERVICE_START";
@Override
public void onCreate() {
super.onCreate();
XLog.i(TAG, "onCreate() ");
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
XLog.i(TAG, "onStart() ");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
XLog.i(TAG, " onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
XLog.i(TAG, "onBind() ");
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
XLog.i(TAG, "onDestroy()");
}
@Override
public boolean onUnbind(Intent intent) {
XLog.i(TAG, "onUnbind()");
return super.onUnbind(intent);
}
}
1.3 在Activity通过startService就可以启动对应的service了
Intent intent = new Intent(BGService.ACTION);
startService(intent);
启动Service输出的log信息:
03-20 14:52:09.541: I/ServiceDemo(19565): MainActivity onPause()
03-20 14:52:22.026: I/ServiceDemo(19565): MainActivity onResume()
03-20 14:52:28.916: I/ServiceDemo(19565): MainActivity onClick() id = 0x7f060000
03-20 14:52:28.918: I/ServiceDemo(19565): BGService onCreate()
03-20 14:52:28.923: I/ServiceDemo(19565): BGService onStartCommand()
03-20 14:52:28.923: I/ServiceDemo(19565): BGService onStart()
这样子启动的service,如果Activity被退出,对应的service是不会被销毁。我们直接按返回键,退出activity。输出的log如下:
03-20 14:54:39.066: I/ServiceDemo(19565): MainActivity onCreate()
03-20 14:54:39.066: I/ServiceDemo(19565): MainActivity onResume()
03-20 14:54:40.827: I/ServiceDemo(19565): MainActivity onClick() id = 0x7f060000
03-20 14:54:40.829: I/ServiceDemo(19565): BGService onCreate()
03-20 14:54:40.829: I/ServiceDemo(19565): BGService onStartCommand()
03-20 14:54:40.829: I/ServiceDemo(19565): BGService onStart()
03-20 14:54:44.800: I/ServiceDemo(19565): MainActivity onPause()
03-20 14:54:45.268: I/ServiceDemo(19565): MainActivity onDestroy()
可以看到,Service的ondestory()函数没有被调用到。
再次去启动该service的时候,只会执行对应的onStartCommand() 和onStart()
03-20 14:57:09.671: I/ServiceDemo(19565): MainActivity onCreate()
03-20 14:57:09.672: I/ServiceDemo(19565): MainActivity onResume()
03-20 14:57:11.120: I/ServiceDemo(19565): MainActivity onClick() id = 0x7f060000
03-20 14:57:11.122: I/ServiceDemo(19565): BGService onCreate()
03-20 14:57:11.133: I/ServiceDemo(19565): BGService onStartCommand()
03-20 14:57:11.133: I/ServiceDemo(19565): BGService onStart()
03-20 14:57:14.626: I/ServiceDemo(19565): MainActivity onPause()
03-20 14:57:15.091: I/ServiceDemo(19565): MainActivity onDestroy()
03-20 14:57:16.610: I/ServiceDemo(19565): MainActivity onCreate()
03-20 14:57:16.610: I/ServiceDemo(19565): MainActivity onResume()
03-20 14:57:19.203: I/ServiceDemo(19565): MainActivity onClick() id = 0x7f060000
03-20 14:57:19.205: I/ServiceDemo(19565): BGService onStartCommand()
03-20 14:57:19.205: I/ServiceDemo(19565): BGService onStart()
1.4 这样子启动的service需要我们自己手动的去停止。
Intent intent = new Intent(BGService.ACTION);
stopService(intent);
1.5 这样子启动service不会调用对应的onBind()和onUnbind()方法
2、另外一种是通过bindService的方法来启动service。
这样子的启动方式,该service和对应的应用是绑定的。如果该应用被销毁,绑定的service也会被销毁。
用这个的好处 是,执行后Service会回调onBind()方法,返回一个实现了IBind的接口类。在客户端操作这个类,就可以和服务端进行通信了。
2.1 首先写好一个ServiceConnect的变量。用来处理onServiceConnected() 和onServiceDisconnected()回调。
private IRemoteService mRemoteService = null;
private ICallback mCallBack = null;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
XLog.i(TAG, "onServiceConnected()");
mRemoteService = (IRemoteService) IRemoteService.Stub.asInterface(service);
mCallBack =new CallBack();
try {
mRemoteService.registerCallBack(mCallBack);
mRemoteService.sendMessageToRemoteService(Util.MSG_START_DOWNLOAD, null);
} catch (RemoteException e) {
XLog.i(TAG, "send start download msg fail! ");
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
XLog.i(TAG, "onServiceDisconnected()");
mRemoteService = null;
}
};
private void bindBGService() {
XLog.i(TAG, "bindBGService()");
Intent service = new Intent(Util.START_BGSERVIVE_ACTION);
bindService(service, mConnection, Context.BIND_AUTO_CREATE);
}
2.3 service里面针对bindService,onBind()方法要返回一个实现了IBind的接口类
@Override
public IBinder onBind(Intent intent) {
XLog.i(TAG, "onBind() ");
mRemoteService = new RemoteService();
return mRemoteService;
}
RemoteService.java,这个是实现了Ibider接口的类。实现AIDL里面写好的interface接口。
package com.android.service.demo;
import android.os.Bundle;
import android.os.RemoteException;
import com.android.demo.aidl.ICallback;
import com.android.demo.aidl.IRemoteService;
public class RemoteService extends IRemoteService.Stub {
private final String TAG = "RemoteService";
private ICallback mICallback = null;
public static final int MSG_DEFAULT = 1;
public static final int MSG_START_DOWNLOAD = MSG_DEFAULT + 1;
public static final int MSG_STOP_DOWNLOAD = MSG_DEFAULT + 2;
public static final int MSG_DOWNLOAD_SUCCESS = MSG_DEFAULT + 3;
public static final int MSG_STOP_SUCCESS = MSG_DEFAULT + 4;
public RemoteService() {
XLog.i(TAG, "RemoteService()");
}
@Override
public void sendMessageToRemoteService(int what, Bundle bundle) throws RemoteException {
XLog.i(TAG, "sendMessageToRemoteService() what = " + what);
switch (what) {
case MSG_START_DOWNLOAD: {
//here service to do something
if (mICallback != null) {
XLog.i(TAG, "send download success message to client");
mICallback.dispatchMessage(MSG_DOWNLOAD_SUCCESS, null);
}
return;
}
case MSG_STOP_DOWNLOAD: {
if (mICallback != null) {
XLog.i(TAG, "send stop success message to client");
mICallback.dispatchMessage(MSG_STOP_SUCCESS, null);
}
return;
}
default:
break;
}
}
@Override
public void registerCallBack(ICallback cb) throws RemoteException {
XLog.i(TAG, "registerCallBack()");
mICallback = cb;
}
}
2.4 当我们bindService的时候,输出的log信息如下:
03-21 15:39:20.776: I/ServiceDemo(8086): MainActivity bindBGService()
03-21 15:39:20.778: I/ServiceDemo(7627): BGService onCreate()
03-21 15:39:20.778: I/ServiceDemo(7627): BGService onBind()
03-21 15:39:20.778: I/ServiceDemo(7627): RemoteService RemoteService()
03-21 15:39:20.787: I/ServiceDemo(8086): MainActivity onServiceConnected()
03-21 15:39:20.788: I/ServiceDemo(7627): RemoteService registerCallBack()
03-21 15:39:20.788: I/ServiceDemo(7627): RemoteService sendRemoteServiceMessage() what = 2
03-21 15:39:20.788: I/ServiceDemo(7627): RemoteService send download success message to client
03-21 15:39:20.788: I/ServiceDemo(8086): CallBack dispatchMessage() what = 4
在bindService的时候,先是把对应的Service启动起来。调用对应的onBind(),这里会返回一个实现IBind接口的类对象 (RemoteService)
当客户端,应用上的onServiceConnected()被回调到,表示已经Activity和service绑定好了。通过返回的IBind对象,Activity就可以直接使用服务端Ibinder对象(RemoteService)的接口了。这样子两个进程之间的通信就建立好了。
2.5 当我们退出Activity的时候,我们可以看到对应的service会被同时销毁
03-21 15:45:55.607: I/ServiceDemo(8086): MainActivity onPause()
03-21 15:45:56.106: I/ServiceDemo(8086): MainActivity onDestroy()
03-21 15:45:56.118: I/ServiceDemo(7627): BGService onUnbind()
03-21 15:45:56.120: I/ServiceDemo(7627): BGService onDestroy()
附件:对应的Demo的code