上次上心理学课的时候,老师讲到沟通,沟通的一个必要前提是心平气和,可是昨天我真的特别气愤,现在的大学生怎么变成这样了!并不是我这个人很保守或是怎样,不喜欢别人女生还要提出那种无耻的要求,学校里又不是红灯区!
好吧,算我说了一些废话。
上回说到要Service有两种:Started 和 Bound,已经学过了Started,因为文档里专门拿出一页来介绍Bound Service,
我估计这个Bound Service 更常用。
首先打开文档:
http://developer.android.com/guide/topics/fundamentals/bound-services.html
1,什么是Bound Service?
Bound Service是在C/S模式下作为服务端(Server)存在,Bound Service允许其他组件绑定这个服务,并且发送请求,接受响应,甚至进行进程间通信(IPC),Bound Service通常依赖于其他应用程序组件,并且不会无限期运行下去。
(有一点我声明一下,就是这些名词我没法翻译,每个人的理解都不一样,我干脆就不翻译了,知道是这么个意思就行了。)
2,基础知识
要创建一个Bound Service:
首先需要继承Service或其子类,这样才算是一个Service
其次需要覆写onBind()方法,这样才算是一个Bound Service
打开API文档:
在Service这个基类里这个方法是抽象方法,需要返回一个实现了IBinder接口的类的对象,这个接口就是声明了客户端可以和Service进行通信。到下面找到更为详细的解释:
这个返回的IBinder对象着实需要花点时间去理解,要实现一个Bound Service,最重要的方法就是这个。文档里提到一点:
Multiple clients can connect to the service at once. However, the system calls your service's onBind() method to retrieve the IBinder only when the first client binds. The system then delivers the same IBinder to any additional clients that bind, without calling onBind() again.
可以有多个客户端同时连接这个Service,但是onBind()方法只会调用一次,返回的也只会有一个IBinder对象,所有连接到这个Service的客户端都是得到这个相同的IBinder对象。
要绑定一个Service,客户端可以调用
boolean bindService (Intent service, ServiceConnection conn, int flags)
![](http://hi.csdn.net/attachment/201110/10/0_1318214418RZM7.gif)
![](http://hi.csdn.net/attachment/201110/10/0_13182155357p5v.gif)
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
找到Binder
在自己定义的类LocalBinder中定义了一个方法:getService()。
再看一下客户端的代码:
public class BindingActivity extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to LocalService Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute) */ public void onButtonClick(View v) { if (mBound) { // Call a method from the LocalService. // However, if this call were something that might hang, then this request should // occur in a separate thread to avoid slowing down the activity performance. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to LocalService, cast the IBinder and get LocalService instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
从onServiceConnected()回调方法中拿到了Service,并赋值给了局部变量,在onStart()方法中调用bindService()绑定Service。
![](http://hi.csdn.net/attachment/201110/10/0_1318218673q0ii.gif)
![](http://hi.csdn.net/attachment/201110/10/0_1318218816yW8Y.gif)
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
在这个Service中有个内部类,IncomingHandler继承Handle,并且覆写了handleMessage()方法。这有牵扯到一个问题:什么是Handle?
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue
今天重点不是这个Handler.
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
我用红色标记了一些代码,
![](http://hi.csdn.net/attachment/201110/10/0_1318221147T0Xa.gif)
![](http://hi.csdn.net/attachment/201110/10/0_1318221301EZTr.gif)
![](http://hi.csdn.net/attachment/201110/10/0_1318221453TXj7.gif)