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
原创粉丝点击