您的位置:首页 > 移动开发 > Android开发

android aidl进程间的通信

2017-04-17 21:55 507 查看
1、IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。进程在PC和移动设备上指的是一个程序或者一个应用。一个进程可以包含多个线程,因此进程和线程是包含被包含的关系。这里主要是实现activity通过aidl调用service方法和一个应用调用另一个应用方法的实现。

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基本是一行一行对应的。

/*
* 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;
}
代码下载地址:http://download.csdn.net/detail/u011324501/9817169




































                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息