1. Local Service Controller
用startService方法启动一个服务,stopService方法停止它。如果没有使用stopService停止服务,即使关闭了当前程序,这个服务依然会运行在后台。
startService(new Intent(Controller.this, LocalService.class));
stopService(new Intent(Controller.this, LocalService.class));
在AndroidManifest.xml中,这个服务只有这个定义,不含任何Intent-Filter,所以只能通过显式的intent调用。
<service android:name=".app.LocalService" />
在服务端,用startService启动的服务会执行onStartCommand方法。
2. Local Service Binding
通过bindService启动服务,unbindService停止服务。可以多个Client绑定服务,一旦没有Client绑定这个服务了,这个服务就会被系统自动销毁。
private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show(); } public void onServiceDisconnected(ComponentName className) { mBoundService = null; Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show(); } };
mConnection定义了ServiceConnection接口,在bindService(new Intent(Binding.this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE)中使用这个链接,当Client和服务建立链接的时候执行onServiceConnected方法,断开链接的时候执行onServiceDisconnected。
执行bindService时,onBind方法会被执行:
public IBinder onBind(Intent intent) { return mBinder; }
这个方法返回一个IBinder对象,Client通过这个对象调用服务的方法 。在本例中通过调用getService()方法获得服务的对象。
3. Messenger Service
通过Messenger进行进程间的通信。整个程序过程是这样的:
final Messenger mMessenger = new Messenger(new IncomingHandler());
先在服务端创建一个Messenger。
bindService(new Intent(Binding.this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);
客户端通过bindService链接服务端。
public IBinder onBind(Intent intent) { return mMessenger.getBinder(); }
服务端通过onBind返回一个Binder对象。
mService = new Messenger(service); Message msg = Message.obtain(null, MessengerService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg);
客户端使用返回的Binder对象构造了一个Messenger。然后可以通过这个Messenger发送信息。replyTo定义了发送信息客户端的Messenger对象,让服务端可以通过这个对象发送信息到客户端。
class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: mValue = msg.arg1; for (int i=mClients.size()-1; i>=0; i--) { try { mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, mValue, 0)); } catch (RemoteException e) { // The client is dead. Remove it from the list; // we are going through the list from back to front // so this is safe to do inside the loop. mClients.remove(i); } } break; default: super.handleMessage(msg); } } }
服务端通过handleMessage接收并处理信息。
4. Remote Service Controller
和Local Service Controller方式很相近。
startService(new Intent("com.example.android.apis.app.REMOTE_SERVICE"));
stopService(new Intent("com.example.android.apis.app.REMOTE_SERVICE"));
AndroidManifest.xml中要定义:
<action android:name="com.example.android.apis.app.REMOTE_SERVICE" />
5. Remote Service Binding
暂时还理解不了,以后补上吧!
6. Service Start Arguments Controller
以工作队列的方式运行Service,运行完成后自动关闭,适用于一些需要长时间运行并且不用返回数据的service。
private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { } } HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper);
新建一个HandlerThread线程来处理客户端的信息。使用HandlerThread创建一个带Looper的线程,而具体的消息处理是由ServiceHandler的handleMessage来处理。
StartService会触发服务端的onStartCommand方法:
public int onStartCommand(Intent intent, int flags, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.arg2 = flags; msg.obj = intent.getExtras(); mServiceHandler.sendMessage(msg); }
通过sendMessage方法给服务端的ServiceHandler发送信息,handleMessage处理信息,完成后关闭service。