To provide binding for service, you must implement the onBind() method. This method returns anIBinder object that defines the interface that clients can use to interact with the service.
三种不同的方式,说白了就是通过onBind()返回三种不同类型的IBinder object。
一、可以返回自定义的Binder(继承自Binder),并且在其中提供public methods that the client can call。
通常情况下,we returns the current Service instance, or an instance of another class hosted by the service with public methods theclient can call.
[html] view plaincopy
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
优点:
1. 使用简单,client在onServiceConnected()拿到Binder之后,可以直接cast到原本的类型,进行使用。
缺点:
1. 必须在同一个进程中使用,因为一般自定义的Binder不会按照IPC的要求实现Binder中的接口,如何支持IPC,请参看AIDL实现的Binder类。
注意:
1. 此种方法调用service的function时,就跟一个普通的函数调用一样,在当前线程执行,而不像IPC那样,service端的function都是在binder thread中执行。
三、使用AIDL,onBind()返回ServiceInterface.Stub mBinder = new ServiceInterface.Stub(){ }。
编译工具会根据.aidl文件生成一个.java文件,里面有AIDL实现的Binder类。例如,我们提供的.aild文件如下:
[html] view plaincopy
package com.baidu.test.aidl;
import com.baidu.test.aidl.ClientInterface;
interface ServiceInterface {
void register(ClientInterface client);
void serviceFun();
void invokeClientCallBack();
}
系统帮我们生成的.java文件如下:
[html] view plaincopy
package com.baidu.test.aidl;
public interface ServiceInterface extends android.os.IInterface {
public void register(com.baidu.test.aidl.ClientInterface client) throws android.os.RemoteException;
public void serviceFun() throws android.os.RemoteException;
public void invokeClientCallBack() throws android.os.RemoteException;
// ======================== Stub用在service端 ================================
public static abstract class Stub extends android.os.Binder implements com.baidu.test.aidl.ServiceInterface {
private static final java.lang.String DESCRIPTOR = "com.baidu.test.aidl.ServiceInterface";
static final int TRANSACTION_register = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_serviceFun = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_invokeClientCallBack = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
public Stub() {
// from Binder, Convenience method for associating a specific interface with the Binder.
// After calling, queryLocalInterface() will return the given owner IInterface
// when the corresponding descriptor is requested.
<span style="color:#FF0000;"><strong>this.attachInterface(this, DESCRIPTOR);</strong></span>
<pre name="code" class="html"> // public void attachInterface (IInterface owner, String descriptor)
}
public static com.baidu.test.aidl.ServiceInterface asInterface(android.os.IBinder obj) {
if ((obj==null)) {
return null;
}
//由于attachInterface()是在service调用的,所以client调用queryLocalInterface()会返回null,从而在client端使用的是Proxy。
<span style="color:#FF0000;"><strong>android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);</strong></span>
if (((iin!=null)&&(iin instanceof com.baidu.test.aidl.ServiceInterface))) {
return ((com.baidu.test.aidl.ServiceInterface)iin);
}
<span style="color:#FF0000;"><strong>return new com.baidu.test.aidl.ServiceInterface.Stub.Proxy(obj);</strong></span>
}
@Override // from IInterface
public android.os.IBinder asBinder() {
return this;
}
@Override // from Binder
// <span style="color:#FF0000;"><strong>service端的Stub实现了onTransact(),service在其中处理client发出的调用,
</strong><span style="color:#000000;"> //</span><strong> 而client端用的Proxy就没有实现onTransact(),而只是调用了transact()。</strong></span>
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_register:
{
data.enforceInterface(DESCRIPTOR);
com.baidu.test.aidl.ClientInterface _arg0;
_arg0 = com.baidu.test.aidl.ClientInterface.Stub.asInterface(data.readStrongBinder());
this.register(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_serviceFun:
{
data.enforceInterface(DESCRIPTOR);
this.serviceFun();
reply.writeNoException();
return true;
}
case TRANSACTION_invokeClientCallBack:
{
data.enforceInterface(DESCRIPTOR);
this.invokeClientCallBack();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
// ======================== Proxy用在client端 ================================
private static class Proxy implements com.baidu.test.aidl.ServiceInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override // from IInterface
public android.os.IBinder asBinder() {
return mRemote;
}
@Override // from IBinder, Get the canonical name of the interface supported by this binder.
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public void register(com.baidu.test.aidl.ClientInterface client) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((client!=null))?(client.asBinder()):(null)));
<span style="color:#FF0000;"><strong>mRemote.transact(Stub.TRANSACTION_register, _data, _reply, 0);</strong></span>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public void serviceFun() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
<strong><span style="color:#FF0000;">mRemote.transact(Stub.TRANSACTION_serviceFun, _data, _reply, 0);</span></strong>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public void invokeClientCallBack() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
<strong><span style="color:#FF0000;">mRemote.transact(Stub.TRANSACTION_invokeClientCallBack, _data, _reply, 0);</span></strong>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
// ======================== Proxy用在client端 end ================================
}
// ======================== Stub用在service端 end ================================
}</pre>
<pre></pre>
service端相关代码如下:<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private final ServiceInterface.Stub mBinder = new ServiceInterface.Stub()</strong></span> {
@Override
public void register(ClientInterface client) throws RemoteException {
}
@Override
public void serviceFun() throws RemoteException {
}
@Override
public void invokeClientCallBack() throws RemoteException {
}
};
@Override
public IBinder onBind(Intent t) {
<strong><span style="color:#FF0000;">return mBinder;</span></strong>
} </pre>client端的相关代码如下:
<p></p>
<p></p>
<pre name="code" class="html"> <strong><span style="color:#FF0000;">private ServiceInterface mService; </span></strong>
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
<strong><span style="color:#FF0000;">mService = ServiceInterface.Stub.asInterface(service);</span></strong>
try {
mService.register(mClient);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};</pre>优点:
<p></p>
<p>1. 可以进行IPC。</p>
<p>缺点:</p>
<p>1. 使用复杂,需要编写.aidl文件,而且client端和service端都需要copy一份.aidl文件,以便编译生成对应的.java文件。</p>
<p>2. 由于service端的函数是在binder thread中执行,而系统又帮我们维护了一个binder thread的线程池,所以我们需要在service的函数中考虑线程安全。<br>
</p>
<p>注意:</p>
<p>1. 如果client和service在同一个进程,那么即使我们采用了AIDL,由系统生成的代码可以看到通过<span style="color:#000000"><strong>ServiceInterface.Stub.asInterface(service)</strong>取得的实例实际上是本地的instance,所以ADIL调用就会变得和一个普通函数调用一样了,也就意味了service端的函数不会在binder thread中执行,而是在当前线程执行了。</span></p>
<p><span style="color:#000000">2. Objects are reference counted across processes.也就是说可能出现内存泄露。<br>
</span></p>
<p></p>
<p><span style="font-size:18px"><strong>二、使用Messager,onBind()返回Messager.getBinder()。</strong></span></p>
<p>Messager可以使用两中不同的方法创建:</p>
<p></p>
<pre name="code" class="html">public Messenger (Handler target)
public Messenger (IBinder target)</pre>
<p></p>
<p>1. 通过传入一个handler创建,service端使用;</p>
<p>2. 通过传入一个binder创建,client端使用。</p>
<p>其实Messager的底层实现还是AIDL,只不过帮我们做了封装,使用更方便。</p>
<p>service端的相关代码如下:</p>
<p></p>
<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private ArrayList<Messenger> mClients = new ArrayList<Messenger>();</strong></span>
<strong><span style="color:#FF0000;">private Messenger mMessenger = new Messenger(new IncomingHandler()); </span></strong>
@Override
public IBinder onBind(Intent t) {
<strong><span style="color:#FF0000;">return mMessenger.getBinder();</span></strong>
}
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Log("===> handleMessage()");
LogThreadInfo();
switch (msg.what) {
case MSG_REGISTER_CLIENT:
<strong><span style="color:#FF0000;">mClients.add(msg.replyTo);</span></strong>
break;
case MSG_UNREGISTER_CLIENT:
<strong><span style="color:#FF0000;">mClients.remove(msg.replyTo);</span></strong>
break;
case MSG_SERVICE_FUN_ALPHA:
for (int i=mClients.size()-1; i>=0; i--) {
try {
<strong><span style="color:#FF0000;">mClients.get(i).send(Message.obtain(null,MSG_SERVICE_FUN_ALPHA));</span></strong>
} catch (RemoteException e) {
// The client is dead. Remove it from the list;
mClients.remove(i);
}
}
break;
default:
super.handleMessage(msg);
}
}
} </pre>
<p></p>
<p>client端的相关代码如下:</p>
<p></p>
<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private Messenger mService = null;</strong></span>
<strong><span style="color:#FF0000;">final Messenger mMessenger = new Messenger(new IncomingHandler());</span></strong>
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SERVICE_FUN_ALPHA:
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
<strong><span style="color:#FF0000;">mService = new Messenger(service);</span></strong>
try {
<span style="color:#FF0000;"><strong>Message msg = Message.obtain(null,MSG_REGISTER_CLIENT);</strong></span>
<strong><span style="color:#FF0000;">msg.replyTo = mMessenger;</span></strong> // 可选项,主要是用来向service注册client,从而实现双向IPC。
<span style="color:#FF0000;"><strong>mService.send(msg);</strong></span>
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
}; </pre>
<p></p>
<p>优点:</p>
<p>1. 比较方便,而且可以实现进程间通信。<br>
</p>
<p>缺点:</p>
<p>1. 必须想办法将Message Id,在service和client之间共享。<br>
</p>
<p>注意:</p>
<p>1. 由于service是在main thread中创建,所以我们的Messager(包括构造Messager所需要提供的Handler)都是在main thread中创建的,所以一般情况下,service端的handleMessage()是在main thread中执行的。当然由于Handler创建时可以自定义所用的Looper,所以我们可以在service的onCreate()里面创建自己的线程,并prepare()线程自己的Looper,然后就可以让service端的handleMessage()运行在我们自己的线程中了。<br>
</p>
<p><br>
</p>
<br>
三种不同的方式,说白了就是通过onBind()返回三种不同类型的IBinder object。
一、可以返回自定义的Binder(继承自Binder),并且在其中提供public methods that the client can call。
通常情况下,we returns the current Service instance, or an instance of another class hosted by the service with public methods theclient can call.
[html] view plaincopy
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
优点:
1. 使用简单,client在onServiceConnected()拿到Binder之后,可以直接cast到原本的类型,进行使用。
缺点:
1. 必须在同一个进程中使用,因为一般自定义的Binder不会按照IPC的要求实现Binder中的接口,如何支持IPC,请参看AIDL实现的Binder类。
注意:
1. 此种方法调用service的function时,就跟一个普通的函数调用一样,在当前线程执行,而不像IPC那样,service端的function都是在binder thread中执行。
三、使用AIDL,onBind()返回ServiceInterface.Stub mBinder = new ServiceInterface.Stub(){ }。
编译工具会根据.aidl文件生成一个.java文件,里面有AIDL实现的Binder类。例如,我们提供的.aild文件如下:
[html] view plaincopy
package com.baidu.test.aidl;
import com.baidu.test.aidl.ClientInterface;
interface ServiceInterface {
void register(ClientInterface client);
void serviceFun();
void invokeClientCallBack();
}
系统帮我们生成的.java文件如下:
[html] view plaincopy
package com.baidu.test.aidl;
public interface ServiceInterface extends android.os.IInterface {
public void register(com.baidu.test.aidl.ClientInterface client) throws android.os.RemoteException;
public void serviceFun() throws android.os.RemoteException;
public void invokeClientCallBack() throws android.os.RemoteException;
// ======================== Stub用在service端 ================================
public static abstract class Stub extends android.os.Binder implements com.baidu.test.aidl.ServiceInterface {
private static final java.lang.String DESCRIPTOR = "com.baidu.test.aidl.ServiceInterface";
static final int TRANSACTION_register = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_serviceFun = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_invokeClientCallBack = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
public Stub() {
// from Binder, Convenience method for associating a specific interface with the Binder.
// After calling, queryLocalInterface() will return the given owner IInterface
// when the corresponding descriptor is requested.
<span style="color:#FF0000;"><strong>this.attachInterface(this, DESCRIPTOR);</strong></span>
<pre name="code" class="html"> // public void attachInterface (IInterface owner, String descriptor)
}
public static com.baidu.test.aidl.ServiceInterface asInterface(android.os.IBinder obj) {
if ((obj==null)) {
return null;
}
//由于attachInterface()是在service调用的,所以client调用queryLocalInterface()会返回null,从而在client端使用的是Proxy。
<span style="color:#FF0000;"><strong>android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);</strong></span>
if (((iin!=null)&&(iin instanceof com.baidu.test.aidl.ServiceInterface))) {
return ((com.baidu.test.aidl.ServiceInterface)iin);
}
<span style="color:#FF0000;"><strong>return new com.baidu.test.aidl.ServiceInterface.Stub.Proxy(obj);</strong></span>
}
@Override // from IInterface
public android.os.IBinder asBinder() {
return this;
}
@Override // from Binder
// <span style="color:#FF0000;"><strong>service端的Stub实现了onTransact(),service在其中处理client发出的调用,
</strong><span style="color:#000000;"> //</span><strong> 而client端用的Proxy就没有实现onTransact(),而只是调用了transact()。</strong></span>
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_register:
{
data.enforceInterface(DESCRIPTOR);
com.baidu.test.aidl.ClientInterface _arg0;
_arg0 = com.baidu.test.aidl.ClientInterface.Stub.asInterface(data.readStrongBinder());
this.register(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_serviceFun:
{
data.enforceInterface(DESCRIPTOR);
this.serviceFun();
reply.writeNoException();
return true;
}
case TRANSACTION_invokeClientCallBack:
{
data.enforceInterface(DESCRIPTOR);
this.invokeClientCallBack();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
// ======================== Proxy用在client端 ================================
private static class Proxy implements com.baidu.test.aidl.ServiceInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override // from IInterface
public android.os.IBinder asBinder() {
return mRemote;
}
@Override // from IBinder, Get the canonical name of the interface supported by this binder.
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
public void register(com.baidu.test.aidl.ClientInterface client) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((client!=null))?(client.asBinder()):(null)));
<span style="color:#FF0000;"><strong>mRemote.transact(Stub.TRANSACTION_register, _data, _reply, 0);</strong></span>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public void serviceFun() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
<strong><span style="color:#FF0000;">mRemote.transact(Stub.TRANSACTION_serviceFun, _data, _reply, 0);</span></strong>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
public void invokeClientCallBack() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
<strong><span style="color:#FF0000;">mRemote.transact(Stub.TRANSACTION_invokeClientCallBack, _data, _reply, 0);</span></strong>
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
// ======================== Proxy用在client端 end ================================
}
// ======================== Stub用在service端 end ================================
}</pre>
<pre></pre>
service端相关代码如下:<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private final ServiceInterface.Stub mBinder = new ServiceInterface.Stub()</strong></span> {
@Override
public void register(ClientInterface client) throws RemoteException {
}
@Override
public void serviceFun() throws RemoteException {
}
@Override
public void invokeClientCallBack() throws RemoteException {
}
};
@Override
public IBinder onBind(Intent t) {
<strong><span style="color:#FF0000;">return mBinder;</span></strong>
} </pre>client端的相关代码如下:
<p></p>
<p></p>
<pre name="code" class="html"> <strong><span style="color:#FF0000;">private ServiceInterface mService; </span></strong>
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
<strong><span style="color:#FF0000;">mService = ServiceInterface.Stub.asInterface(service);</span></strong>
try {
mService.register(mClient);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};</pre>优点:
<p></p>
<p>1. 可以进行IPC。</p>
<p>缺点:</p>
<p>1. 使用复杂,需要编写.aidl文件,而且client端和service端都需要copy一份.aidl文件,以便编译生成对应的.java文件。</p>
<p>2. 由于service端的函数是在binder thread中执行,而系统又帮我们维护了一个binder thread的线程池,所以我们需要在service的函数中考虑线程安全。<br>
</p>
<p>注意:</p>
<p>1. 如果client和service在同一个进程,那么即使我们采用了AIDL,由系统生成的代码可以看到通过<span style="color:#000000"><strong>ServiceInterface.Stub.asInterface(service)</strong>取得的实例实际上是本地的instance,所以ADIL调用就会变得和一个普通函数调用一样了,也就意味了service端的函数不会在binder thread中执行,而是在当前线程执行了。</span></p>
<p><span style="color:#000000">2. Objects are reference counted across processes.也就是说可能出现内存泄露。<br>
</span></p>
<p></p>
<p><span style="font-size:18px"><strong>二、使用Messager,onBind()返回Messager.getBinder()。</strong></span></p>
<p>Messager可以使用两中不同的方法创建:</p>
<p></p>
<pre name="code" class="html">public Messenger (Handler target)
public Messenger (IBinder target)</pre>
<p></p>
<p>1. 通过传入一个handler创建,service端使用;</p>
<p>2. 通过传入一个binder创建,client端使用。</p>
<p>其实Messager的底层实现还是AIDL,只不过帮我们做了封装,使用更方便。</p>
<p>service端的相关代码如下:</p>
<p></p>
<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private ArrayList<Messenger> mClients = new ArrayList<Messenger>();</strong></span>
<strong><span style="color:#FF0000;">private Messenger mMessenger = new Messenger(new IncomingHandler()); </span></strong>
@Override
public IBinder onBind(Intent t) {
<strong><span style="color:#FF0000;">return mMessenger.getBinder();</span></strong>
}
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Log("===> handleMessage()");
LogThreadInfo();
switch (msg.what) {
case MSG_REGISTER_CLIENT:
<strong><span style="color:#FF0000;">mClients.add(msg.replyTo);</span></strong>
break;
case MSG_UNREGISTER_CLIENT:
<strong><span style="color:#FF0000;">mClients.remove(msg.replyTo);</span></strong>
break;
case MSG_SERVICE_FUN_ALPHA:
for (int i=mClients.size()-1; i>=0; i--) {
try {
<strong><span style="color:#FF0000;">mClients.get(i).send(Message.obtain(null,MSG_SERVICE_FUN_ALPHA));</span></strong>
} catch (RemoteException e) {
// The client is dead. Remove it from the list;
mClients.remove(i);
}
}
break;
default:
super.handleMessage(msg);
}
}
} </pre>
<p></p>
<p>client端的相关代码如下:</p>
<p></p>
<pre name="code" class="html"> <span style="color:#FF0000;"><strong>private Messenger mService = null;</strong></span>
<strong><span style="color:#FF0000;">final Messenger mMessenger = new Messenger(new IncomingHandler());</span></strong>
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SERVICE_FUN_ALPHA:
break;
default:
super.handleMessage(msg);
}
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
<strong><span style="color:#FF0000;">mService = new Messenger(service);</span></strong>
try {
<span style="color:#FF0000;"><strong>Message msg = Message.obtain(null,MSG_REGISTER_CLIENT);</strong></span>
<strong><span style="color:#FF0000;">msg.replyTo = mMessenger;</span></strong> // 可选项,主要是用来向service注册client,从而实现双向IPC。
<span style="color:#FF0000;"><strong>mService.send(msg);</strong></span>
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
}; </pre>
<p></p>
<p>优点:</p>
<p>1. 比较方便,而且可以实现进程间通信。<br>
</p>
<p>缺点:</p>
<p>1. 必须想办法将Message Id,在service和client之间共享。<br>
</p>
<p>注意:</p>
<p>1. 由于service是在main thread中创建,所以我们的Messager(包括构造Messager所需要提供的Handler)都是在main thread中创建的,所以一般情况下,service端的handleMessage()是在main thread中执行的。当然由于Handler创建时可以自定义所用的Looper,所以我们可以在service的onCreate()里面创建自己的线程,并prepare()线程自己的Looper,然后就可以让service端的handleMessage()运行在我们自己的线程中了。<br>
</p>
<p><br>
</p>
<br>
发表评论
-
android 应用内存分析
2013-03-11 17:53 2700Dalvik虚拟机支持垃圾收 ... -
NDK开发环境搭建_r8(转贴)
2012-12-21 15:03 925NDK开发环境搭建_r8 本文主内容: 1、 ... -
JSON数据的上传与解析过程
2012-10-31 17:56 11794Anroid上数据的交互有很多,XML,JSON,SOCKET ... -
android json解析及简单例子
2012-10-31 17:55 658JSON的定义: ... -
Android Service那些不得不说的事-之一
2012-10-31 10:28 4127必须谨记的几点: 1. service的所有onXXXX( ... -
AsyncTask的源码分析 与 使用 之我的浅解
2012-10-11 10:22 1490由于主线程负责处理用 ... -
Android多线程任务优化:实现后台预读线程
2012-10-11 10:20 4092Android多线程任务优化:实现后台预读线程 分类: And ...
相关推荐
Android Service之bound实现
关于Android Service的简单实例:属于start service类型,而不是bound service。
On a search problem related to branch-and-bound procedures.pdfOn a search problem related to branch-and-bound procedures.pdfOn a search problem related to branch-and-bound procedures.pdfOn a search ...
IE598NH-lecture-20-Lower Complexity Bound in Stochastic Optimization.pdfIE598NH-lecture-20-Lower Complexity Bound in Stochastic Optimization.pdf
What is the Cramer-Rao Lower Bound
分支定界法求解TSp问题的分析研究以及matlab实现
代码比较简单,但是步骤结合博客还是很详细的,可以看我的博客http://blog.csdn.net/superbiglw/article/details/53156177
绑定服务BoundService之Messenger双向通信的实现
STC-TCC-232-0201-01-CN-用bound方式建立2层数据流[整理].pdf
一个扩展的IBinder类实现通信的简单例子
本文首次将Bekenstein公式和面向信息的方法结合起来,从理论上计算出可实现的最小晶粒长度以及信息的能量和数量。 由于信息方法基于对物理现象模型中包含的信息量的计算,因此这成为可能。 结果表明,至少在长度...
This is an example of array out bound i.e out of its memory limit and this is developed in C#
Service通常总是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件: 1.并不依赖于...
lower_bound函数代码(C++实现).rar
lighttpd: fix /usr/lib/mod_cgi.so: undefined symbol: chunkqueue_written
rcpsp
在实际应用着经常需要求解非线性整数规划或混合规划问题,该领域中的一种常用的算法是分支定界(branch and bound)算法,但是matlab工具箱中没有相关的函数。荷兰Groningen大学的Koert Kuipers编写的的BNB20工具箱...
Service在Android中是一种长生命周期的组件,它不实现任何用户界面。最常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如文件下载程序,它可以在后台执行文件的下载。 让我们来...
NULL 博文链接:https://samson7b.iteye.com/blog/1393458
lower_bound函数lower_bound函数用法及应用领域和案例分享lower_bound函数用法及应用领域和案例分享lower_bound函数用法及应用领域和案例分享lower_bound函数用法及应用领域和案例分享lower_bound函数用法及应用领域...