android aidl进程间的通信

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









































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值