本文参考http://blog.csdn.net/saintswordsman/article/details/5130947
android的多进程是通过Binder来实现的,一个类,继承了Binder,那么它的对象就可以被远程的进程使用了(前提是远程进程获取了这个类的对象【对象的引用】,至于如如何获得看下文),怎么使用呢?在Android中, 则采用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现,所以我们必须写后缀为.aidl的文件。.aidl文件放在src下面,刷新一下就会生成同名的.java文件
文件:forActivity.aidl
-
package com.styleflying.AIDL;
-
interface forActivity {
-
void performAction();
-
}
文件:forService.aidl
-
package com.styleflying.AIDL;
-
import com.styleflying.AIDL.forActivity;
-
interface forService {
-
void registerTestCall(forActivity cb);
-
void invokCallBack();
-
}
这两个文件和Java文件放置的地方一样,看包名。
在Eclipse中它们将被自动编译为forActivity.java和forService.java,它们存放在gen目录下。为了方便手头无法演练的读者,代码贴上,不用细看。
文件forActivity.java:
-
-
-
-
-
package com.styleflying.AIDL;
-
import java.lang.String;
-
import android.os.RemoteException;
-
import android.os.IBinder;
-
import android.os.IInterface;
-
import android.os.Binder;
-
import android.os.Parcel;
-
public interface forActivity extends android.os.IInterface
-
{
-
-
public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forActivity
-
{
-
private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forActivity";
-
-
public Stub()
-
{
-
this.attachInterface(this, DESCRIPTOR);
-
}
-
-
-
-
-
public static com.styleflying.AIDL.forActivity asInterface(android.os.IBinder obj)
-
{
-
if ((obj==null)) {
-
return null;
-
}
-
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
-
if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forActivity))) {
-
return ((com.styleflying.AIDL.forActivity)iin);
-
}
-
return new com.styleflying.AIDL.forActivity.Stub.Proxy(obj);
-
}
-
public android.os.IBinder asBinder()
-
{
-
return this;
-
}
-
@Override 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_performAction:
-
{
-
data.enforceInterface(DESCRIPTOR);
-
this.performAction();
-
reply.writeNoException();
-
return true;
-
}
-
}
-
return super.onTransact(code, data, reply, flags);
-
}
-
private static class Proxy implements com.styleflying.AIDL.forActivity
-
{
-
private android.os.IBinder mRemote;
-
Proxy(android.os.IBinder remote)
-
{
-
mRemote = remote;
-
}
-
public android.os.IBinder asBinder()
-
{
-
return mRemote;
-
}
-
public java.lang.String getInterfaceDescriptor()
-
{
-
return DESCRIPTOR;
-
}
-
public void performAction() throws android.os.RemoteException
-
{
-
android.os.Parcel _data = android.os.Parcel.obtain();
-
android.os.Parcel _reply = android.os.Parcel.obtain();
-
try {
-
_data.writeInterfaceToken(DESCRIPTOR);
-
mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);
-
_reply.readException();
-
}
-
finally {
-
_reply.recycle();
-
_data.recycle();
-
}
-
}
-
}
-
static final int TRANSACTION_performAction = (IBinder.FIRST_CALL_TRANSACTION + 0);
-
}
-
public void performAction() throws android.os.RemoteException;
-
}
文件forService.java:
-
-
-
-
-
package com.styleflying.AIDL;
-
import java.lang.String;
-
import android.os.RemoteException;
-
import android.os.IBinder;
-
import android.os.IInterface;
-
import android.os.Binder;
-
import android.os.Parcel;
-
public interface forService extends android.os.IInterface
-
{
-
-
public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forService
-
{
-
private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forService";
-
-
public Stub()
-
{
-
this.attachInterface(this, DESCRIPTOR);
-
}
-
-
-
-
-
public static com.styleflying.AIDL.forService asInterface(android.os.IBinder obj)
-
{
-
if ((obj==null)) {
-
return null;
-
}
-
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
-
if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forService))) {
-
return ((com.styleflying.AIDL.forService)iin);
-
}
-
return new com.styleflying.AIDL.forService.Stub.Proxy(obj);
-
}
-
public android.os.IBinder asBinder()
-
{
-
return this;
-
}
-
@Override 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_registerTestCall:
-
{
-
data.enforceInterface(DESCRIPTOR);
-
com.styleflying.AIDL.forActivity _arg0;
-
_arg0 = com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());
-
this.registerTestCall(_arg0);
-
reply.writeNoException();
-
return true;
-
}
-
case TRANSACTION_invokCallBack:
-
{
-
data.enforceInterface(DESCRIPTOR);
-
this.invokCallBack();
-
reply.writeNoException();
-
return true;
-
}
-
}
-
return super.onTransact(code, data, reply, flags);
-
}
-
private static class Proxy implements com.styleflying.AIDL.forService
-
{
-
private android.os.IBinder mRemote;
-
Proxy(android.os.IBinder remote)
-
{
-
mRemote = remote;
-
}
-
public android.os.IBinder asBinder()
-
{
-
return mRemote;
-
}
-
public java.lang.String getInterfaceDescriptor()
-
{
-
return DESCRIPTOR;
-
}
-
public void registerTestCall(com.styleflying.AIDL.forActivity cb) 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((((cb!=null))?(cb.asBinder()):(null)));
-
mRemote.transact(Stub.TRANSACTION_registerTestCall, _data, _reply, 0);
-
_reply.readException();
-
}
-
finally {
-
_reply.recycle();
-
_data.recycle();
-
}
-
}
-
public void invokCallBack() throws android.os.RemoteException
-
{
-
android.os.Parcel _data = android.os.Parcel.obtain();
-
android.os.Parcel _reply = android.os.Parcel.obtain();
-
try {
-
_data.writeInterfaceToken(DESCRIPTOR);
-
mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);
-
_reply.readException();
-
}
-
finally {
-
_reply.recycle();
-
_data.recycle();
-
}
-
}
-
}
-
static final int TRANSACTION_registerTestCall = (IBinder.FIRST_CALL_TRANSACTION + 0);
-
static final int TRANSACTION_invokCallBack = (IBinder.FIRST_CALL_TRANSACTION + 1);
-
}
-
public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException;
-
public void invokCallBack() throws android.os.RemoteException;
-
}
我们可以看到在.java文件中都定义了一个抽象类Stub,Stub就是继承Binder。
好了,那我们那里用到了Binder呢?没错,就是Service,Service使用有两种方法,startService,bindeService。bindeService时在实现Service就必须实现 onBind 返回一个Binder对象,这个Binder对象就会被activity回调使用。这样activity跟service就可以通信了。当然是activity可以调用service了。接下来的例子还实现了相互调用。
看mAIDLService.java:
-
package com.styleflying.AIDL;
-
import android.app.Service;
-
import android.content.Intent;
-
import android.os.IBinder;
-
import android.os.RemoteCallbackList;
-
import android.os.RemoteException;
-
import android.util.Log;
-
public class mAIDLService extends Service {
-
private static final String TAG = "AIDLService";
-
private forActivity callback;
-
private void Log(String str) {
-
Log.d(TAG, "------ " + str + "------");
-
}
-
@Override
-
public void onCreate() {
-
Log("service create");
-
}
-
@Override
-
public void onStart(Intent intent, int startId) {
-
Log("service start id=" + startId);
-
}
-
-
@Override
-
public IBinder onBind(Intent t) {
-
Log("service on bind");
-
return mBinder;
-
}
-
@Override
-
public void onDestroy() {
-
Log("service on destroy");
-
super.onDestroy();
-
}
-
@Override
-
public boolean onUnbind(Intent intent) {
-
Log("service on unbind");
-
return super.onUnbind(intent);
-
}
-
public void onRebind(Intent intent) {
-
Log("service on rebind");
-
super.onRebind(intent);
-
}
-
private final forService.Stub mBinder = new forService.Stub() {
-
@Override
-
public void invokCallBack() throws RemoteException
-
{
-
callback.performAction();
-
-
}
-
@Override
-
public void registerTestCall(forActivity cb) throws RemoteException
-
{
-
callback = cb;
-
-
}
-
-
};
-
}
其中mBinder就是给activity调用了。然而这个类中的mBinder 中的registerTestCall传递的forActivity就是能service调用activity用的。
看mAIDLActivity.java:
-
package com.styleflying.AIDL;
-
import android.app.Activity;
-
import android.content.ComponentName;
-
import android.content.Context;
-
import android.content.Intent;
-
import android.content.ServiceConnection;
-
import android.os.Bundle;
-
import android.os.IBinder;
-
import android.os.RemoteException;
-
import android.util.Log;
-
import android.view.View;
-
import android.view.View.OnClickListener;
-
import android.widget.Button;
-
import android.widget.Toast;
-
public class mAIDLActivity extends Activity {
-
private static final String TAG = "AIDLActivity";
-
private Button btnOk;
-
private Button btnCancel;
-
private Button btnCallBack;
-
-
private void Log(String str) {
-
Log.d(TAG, "------ " + str + "------");
-
}
-
-
private forActivity mCallback = new forActivity.Stub() {
-
public void performAction() throws RemoteException
-
{
-
Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
-
}
-
};
-
-
forService mService;
-
private ServiceConnection mConnection = new ServiceConnection() {
-
public void onServiceConnected(ComponentName className,
-
IBinder service) {
-
mService = forService.Stub.asInterface(service);
-
try {
-
mService.registerTestCall(mCallback);}
-
catch (RemoteException e) {
-
-
}
-
}
-
public void onServiceDisconnected(ComponentName className) {
-
Log("disconnect service");
-
mService = null;
-
}
-
};
-
@Override
-
public void onCreate(Bundle icicle) {
-
super.onCreate(icicle);
-
setContentView(R.layout.main);
-
btnOk = (Button)findViewById(R.id.btn_ok);
-
btnCancel = (Button)findViewById(R.id.btn_cancel);
-
btnCallBack = (Button)findViewById(R.id.btn_callback);
-
btnOk.setOnClickListener(new OnClickListener() {
-
public void onClick(View v) {
-
Bundle args = new Bundle();
-
Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
-
intent.putExtras(args);
-
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-
startService(intent);
-
}
-
});
-
btnCancel.setOnClickListener(new OnClickListener() {
-
public void onClick(View v) {
-
unbindService(mConnection);
-
-
}
-
});
-
btnCallBack.setOnClickListener(new OnClickListener() {
-
-
@Override
-
public void onClick(View v)
-
{
-
try
-
{
-
mService.invokCallBack();
-
} catch (RemoteException e)
-
{
-
-
e.printStackTrace();
-
}
-
}
-
});
-
}
-
}
其中按钮点击bindeService时就会触发ServiceConnection,返回了mService = forService.Stub.asInterface(service); activity跟service实现了通信,再mService.registerTestCall(mCallback);} 这样service跟activity又能通信了。在mService.invokCallBack();顺序是activity->service->activity
还有几篇android多进程通信写得不错一并贴出来
http://www.cnblogs.com/BeyondAnyTime/p/3204119.html
http://www.apkbus.com/android-83462-1-1.html
http://blog.csdn.net/baodinglaolang/article/details/9903499android 多进程 Binder AIDL Service
原文:http://blog.csdn.net/chaoyue0071/article/details/44286435