Android AIDL 详解

为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

说了一堆没用的那么AIDL 到底如何应用在我们的开发中,就是当我们的程序需要访问其他程序的服务中的数据。或者我们的程序开了多进程的需要数据交互的时候就可以使用。其实aidl 用的就是binder机制。

那么如何使用aidl 呢 我这里 讲实现代码 按照顺序 贴出来。

1.创建 aidl 文件 定义一个接口 负责定义 服务端提供的方法。

<span style="font-size:18px;">package com.yu.alitestpay;

// 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.
     */
    void basicTypes(String str);
}</span>

3.创建 Service 类 。 实现service 端的具体方法。供 客户端使用 。

<span style="font-size:18px;">package com.yu.alitestpay;

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;</span>
<span style="font-size:18px;">public class Mservice extends Service
{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
}
    private IMyAidlInterface.Stub binder= new  IMyAidlInterface.Stub(){
        @Override
        public void basicTypes(String str) throws RemoteException {
                     Log.i("2024","服务端执行了方法");
        }
    };
}
</span>
4.客户端 通过 onServiceConnected 方法 调用服务端 方法 完成数据交互 。
<span style="font-size:18px;"></pre><pre name="code" class="html">ServiceConnection cs=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                IMyAidlInterface proxy=IMyAidlInterface.Stub.asInterface(service);
                try {
                    proxy.basicTypes("2342");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };</span>

下面贴出 IMyAidlInterface 类的源码   讲下 binder 在aidl 中的 应用。

查看 IMyAidlInterface.java 中可以看到两个类 一个stub  一个 proxy   Stub 集成了binder 实现了IMyAidlInterface 那么IMyAidlInterface 中的抽象方法
他没有实现 为什么 是留着我们写 service 的时候交给service写 具体 实现方法。就像这里的 new  IMyAidlInterface.Stub() 这里就具体实现了方法
 服务端 
我们在 onbind 的时候返回了binder 对象 也就是实现了具体抽象方法的Stub 对象 。
客户端
客户端在  这里用stub 获得了一个对象 其实获得就是proxy 我们客户端的basicTypes()方法  调用了 stub 的transact sub继承了 binder 所以看源码发现 transact 的时候会调用ontransact  那么 stub 的ontransact 方法调用了什么  调用了 this.basicTypes  那么这个方法就是 这里面实现的方法
整个交互过程完成 一个典型的binder 机制。

<span style="font-size:18px;">/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: F:\\android\\AliTestPay\\app\\src\\main\\aidl\\com\\yu\\alitestpay\\IMyAidlInterface.aidl
 */
package com.yu.alitestpay;
// 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.yu.alitestpay.IMyAidlInterface
{
private static final java.lang.String DESCRIPTOR = "com.yu.alitestpay.IMyAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.yu.alitestpay.IMyAidlInterface interface,
 * generating a proxy if needed.
 */
public static com.yu.alitestpay.IMyAidlInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.yu.alitestpay.IMyAidlInterface))) {
return ((com.yu.alitestpay.IMyAidlInterface)iin);
}
return new com.yu.alitestpay.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_basicTypes:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
this.basicTypes(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.yu.alitestpay.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;
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
@Override public void basicTypes(java.lang.String str) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(str);
mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
/**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
public void basicTypes(java.lang.String str) throws android.os.RemoteException;
}
</span>
 

猜你喜欢

转载自blog.csdn.net/ImTryCatchException/article/details/52635332