android aidl进程间的通信
2017-04-17 21:55
507 查看
1、IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。进程在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系。这里主要是实现activity通过aidl调用service方法和一个应用调用另一个应用方法的实现。
2、aidl在应用间的使用
首先可以先实现 .aidl文件,.aidl文件可以直接新建,跟java同级
service和activity连接需要使用ServiceConnection,里面实现了两个方法,连接和断开连接。建立连接后就可以对service实例进行引用了,当建立连接需要调用aidlInterface = IMyAidlInterface.Stub.asInterface(service);如下所示,使用完还要在onDestroy里调用unbindService(connection);
最后记得在build.gradl里面的android{}加入下面代码,以便实现对.aidl文件的调用。
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
实现效果
3、这里是activity调用service方法的实现。下面实现一下不同应用间的通信实现。上面的实现算是服务端,下面实现一下客户端代码
客户端的.aidl 文件直接拷贝服务端的就可以,保持好同样的路径,代码中实现需要注意的是在5.0以上的系统中启动服务需要用setPackage,否则报错,填写是服务端的包名,其他没什么注意的了。详细可以看下面代码:
4、了解一下IMyAidlInterface里面的代码,就是服务端和客户端是如何建立关联的。服务端提供的服务是由IMyAidlInterface.Stub来执行,Stub这个类是Binder的子类,继承了binder的,而且mBinder实现了IMyAidlInterface接口的方法。
我们在.aidl文件里面添加的两个方法在这里都可以看到
这个proxy实例传入了我们的binder驱动,并且封装了我们调用服务端的代码,客户端通过Binder驱动的transact()方法调用服务端代码。
首先声明两个parce对象,一个用于传递数据,一个用于接收返回的数据。与服务端的enforceInterfac对应。
最后读出我们服务端返回的数据,然后return。可以看到和服务端的onTransact基本是一行一行对应的。
2、aidl在应用间的使用
首先可以先实现 .aidl文件,.aidl文件可以直接新建,跟java同级
// IMyAidlInterface.aidl package com.example.apple.myfragment; // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ int add(int a, int b); int reduce(int a,int b); }这里只写两个方法,add和reduce,这里通过aidl将service和activity绑定,这样可以实现activity对service里面的方法的调用,要让service支持绑定,需要实现onBind方法,并反回被绑定service的当前实例。需要注意的是更新完。aidl文件需要刷新一下工程,service代码如下所示:
package com.example.apple.myfragment; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.support.annotation.Nullable; import android.util.Log; /** * Created by apple on 17/4/14. */ public class MyService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return myAidlInterface; } private final IMyAidlInterface.Stub myAidlInterface = new IMyAidlInterface.Stub() { @Override public int add(int a, int b) throws RemoteException { Log.e("nsc","a+b="+(a+b)); return a+b; } @Override public int reduce(int a, int b) throws RemoteException { Log.e("nsc","a-b="+(a-b)); return rd(a,b); } }; private int rd(int a ,int b){ if (a>b){ return a-b; }else { return b-a; } } }
service和activity连接需要使用ServiceConnection,里面实现了两个方法,连接和断开连接。建立连接后就可以对service实例进行引用了,当建立连接需要调用aidlInterface = IMyAidlInterface.Stub.asInterface(service);如下所示,使用完还要在onDestroy里调用unbindService(connection);
package com.example.apple.myfragment; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private Button btnAdd; private Button btnReduce; private TextView tvResult; private IMyAidlInterface aidlInterface; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { aidlInterface = IMyAidlInterface.Stub.asInterface(service); } /** * 断开连接 * @param name */ @Override public void onServiceDisconnected(ComponentName name) { aidlInterface = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); bindAndStartService(); } /** * 绑定服务 */ private void bindAndStartService() { Intent intent = new Intent(this, MyService.class); intent.setAction("com.example.apple.myfragment"); bindService(intent, connection, Context.BIND_AUTO_CREATE); startService(intent); } private void initView() { tvResult = (TextView)findViewById(R.id.tv_result); btnAdd = (Button)findViewById(R.id.btn_add); btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { if (aidlInterface!=null){ tvResult.setText(aidlInterface.add(3,4)+""); } }catch (Exception e){ e.printStackTrace(); } } }); btnReduce = (Button)findViewById(R.id.btn_reduce); btnReduce.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { if (aidlInterface!=null){ tvResult.setText(aidlInterface.reduce(5,3)+""); } }catch (Exception e){ e.printStackTrace(); } } }); } @Override protected void onDestroy() { unbindService(connection); super.onDestroy(); } }还要在manifest里面配置一下
<service android:name=".MyService"> <intent-filter> <action android:name="com.example.apple.myfragment"></action> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </service>
最后记得在build.gradl里面的android{}加入下面代码,以便实现对.aidl文件的调用。
sourceSets {
main {
java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
实现效果
3、这里是activity调用service方法的实现。下面实现一下不同应用间的通信实现。上面的实现算是服务端,下面实现一下客户端代码
客户端的.aidl 文件直接拷贝服务端的就可以,保持好同样的路径,代码中实现需要注意的是在5.0以上的系统中启动服务需要用setPackage,否则报错,填写是服务端的包名,其他没什么注意的了。详细可以看下面代码:
/** * 绑定服务 */ private void bindAndStartService() { Intent intent = new Intent(); intent.setAction("com.example.apple.myfragment"); intent.setPackage("com.example.apple.myfragment"); bindService(intent, connection, Context.BIND_ABOVE_CLIENT); }MainActivity代码实现
package com.example.apple.aidl; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.example.apple.aidlactivity.R; import com.example.apple.myfragment.IMyAidlInterface; public class MainActivity extends AppCompatActivity { private Button btnAdd; private Button btnReduce; private TextView tvResult; private IMyAidlInterface aidlInterface; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { aidlInterface = IMyAidlInterface.Stub.asInterface(service); } /** * 断开连接 * @param name */ @Override public void onServiceDisconnected(ComponentName name) { aidlInterface = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); bindAndStartService(); } /** * 绑定服务 */ private void bindAndStartService() { Intent intent = new Intent(); intent.setAction("com.example.apple.myfragment"); intent.setPackage("com.example.apple.myfragment"); bindService(intent, connection, Context.BIND_ABOVE_CLIENT); } private void initView() { tvResult = (TextView)findViewById(R.id.tv_result); btnAdd = (Button)findViewById(R.id.btn_add); btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // bindAndStartService(); try { // if (aidlInterface!=null){ tvResult.setText(aidlInterface.add(3,4)+""); // } }catch (Exception e){ e.printStackTrace(); } } }); btnReduce = (Button)findViewById(R.id.btn_reduce); btnReduce.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { if (aidlInterface!=null){ tvResult.setText(aidlInterface.reduce(5,3)+""); } }catch (Exception e){ e.printStackTrace(); } } }); } @Override protected void onDestroy() { unbindService(connection); super.onDestroy(); } }
4、了解一下IMyAidlInterface里面的代码,就是服务端和客户端是如何建立关联的。服务端提供的服务是由IMyAidlInterface.Stub来执行,Stub这个类是Binder的子类,继承了binder的,而且mBinder实现了IMyAidlInterface接口的方法。
public interface IMyAidlInterface extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.apple.myfragment.IMyAidlInterface { private static final java.lang.String DESCRIPTOR = "com.example.apple.myfragment.IMyAidlInterface";
我们在.aidl文件里面添加的两个方法在这里都可以看到
@Override public int add(int a, int b) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b); mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public int reduce(int a, int b) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b); mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); } finally { _reply.recycle(); _data.recycle(); } return _result; } }
这个proxy实例传入了我们的binder驱动,并且封装了我们调用服务端的代码,客户端通过Binder驱动的transact()方法调用服务端代码。
首先声明两个parce对象,一个用于传递数据,一个用于接收返回的数据。与服务端的enforceInterfac对应。
_data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b);写入需要传递的数据。
mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0);
最后读出我们服务端返回的数据,然后return。可以看到和服务端的onTransact基本是一行一行对应的。
/*代码下载地址:http://download.csdn.net/detail/u011324501/9817169
* This file is auto-generated. DO NOT MODIFY.
* Original file: /Users/apple/Desktop/MyFragment/app/src/main/aidl/com/example/apple/myfragment/IMyAidlInterface.aidl
*/
package com.example.apple.myfragment;
// Declare any non-default types here with import statements
public interface IMyAidlInterface extends android.os.IInterface { /** * Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.apple.myfragment.IMyAidlInterface { private static final java.lang.String DESCRIPTOR = "com.example.apple.myfragment.IMyAidlInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.apple.myfragment.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.example.apple.myfragment.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.example.apple.myfragment.IMyAidlInterface))) {
return ((com.example.apple.myfragment.IMyAidlInterface) iin);
}
return new com.example.apple.myfragment.IMyAidlInterface.Stub.Proxy(obj);
}
@Override
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_add: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.add(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_reduce: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
int _result = this.reduce(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.apple.myfragment.IMyAidlInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public int add(int a, int b) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public int reduce(int a, int b) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeInt(b);
mRemote.transact(Stub.TRANSACTION_reduce, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_reduce = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public int add(int a, int b) throws android.os.RemoteException;
public int reduce(int a, int b) throws android.os.RemoteException;
}
相关文章推荐
- android 进程通信--aidl
- Android开发之使用AIDL和远程服务实现进程通信
- Android使用AIDL跨进程通信
- Android 使用AIDL实现进程之间的通信(一)
- Android跨进程通信,深入浅出AIDL
- Android IPC机制(三)——利用AIDL实现跨进程通信
- Android跨进程通信-AIDL
- Android进程间的通信之AIDL
- Android跨进程通信之AIDL机制和广播机制的异同
- 实例讲解Android中的AIDL内部进程通信接口使用
- Android 跨进程通信: AIDL
- 【随心笔录】Android AIDL使用,实现跨进程通信
- Android进程通信之AIDL
- Android中的跨进程通信方法实例及特点分析(一):AIDL Service
- Android 进程通信机制之 AIDL
- Android进程通信之Messenger和AIDL使用详解
- Aidl跨进程通信机制-android学习之旅(87)
- 从AIDL开始谈Android进程间Binder通信机制
- Android AIDL实现两个APP间的跨进程通信实例
- Android学习之跨进程通信安卓接口定义语言AIDL(一)