android aidl进程间的通信
来源:互联网 发布:镜片种类知乎 编辑:程序博客网 时间:2024/06/07 18:15
1、IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。进程在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系。这里主要是实现activity通过aidl调用service方法和一个应用调用另一个应用方法的实现。
2、aidl在应用间的使用
首先可以先实现 .aidl文件,.aidl文件可以直接新建,跟java同级
// IMyAidlInterface.aidlpackage com.example.apple.myfragment;// Declare any non-default types here with import statementsinterface 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基本是一行一行对应的。
/* * 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 statementspublic 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;}代码下载地址:http://download.csdn.net/detail/u011324501/9817169
0 0
- Android:进程间的通信: AIDL
- android的AIDL----讲述进程间通信
- android进程间通信-aidl的使用
- android进程间的通信方式AIDL
- android的进程间通信----aidl
- android AIDL实现进程间的通信
- Android初级教程进程间的通信AIDL
- Android的AIDL进程间通信
- Android进程间通信AIDL的demo
- Android进程间的通信之AIDL
- android aidl进程间的通信
- Android进程间的通信:Mesenger、aidl
- AIDL实现Android进程间的通信
- Android.进程间的通信之AIDL
- android AIDL 进程间通信
- android aidl进程间通信
- Android 进程间通信AIDL
- Android进程间通信--AIDL
- Genymotion的安装与使用(附百度云盘下载地址,全套都有,无需注册Genymotion即可使用)
- 几种排序总结(转载的)
- Longest Uncommon Subsequence I
- KMP算法
- Java线程池及用法
- android aidl进程间的通信
- B+,B*到R树
- 并发随笔(1)
- 线程组
- 查找---顺序查找
- VR系列——Oculus Rift入门手册:一、SDK入门
- 使用zabbix的java api来对主机进行删除时的bug说明
- 关于php项目的开发回顾总结第五章-----BUG之美
- sevlet