IPC通信之AIDL

IPC通信之AIDL

AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似。 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。 在 Android 上,一个进程通常无法访问另一个进程的内存。 尽管如此,进程需要将其对象分解成操作系统能够识别的原语,并将对象编组成跨越边界的对象。 编写执行这一编组操作的代码是一项繁琐的工作,因此 Android 会使用 AIDL 来处理。

注:只有允许不同应用的客户端用 IPC 方式访问服务,并且想要在服务中处理多线程时,才有必要使用 AIDL。 如果您不需要执行跨越不同应用的并发 IPC,就应该通过实现一个 Binder 创建接口;或者,如果您想执行 IPC,但根本不需要处理多线程,则使用 Messenger 类来实现接口。无论如何,在实现 AIDL 之前,请您务必理解绑定服务。

AIDL接口定义

.aidl支持int,String,boolean,charSequence、List、Map这些数据类型以及实现Parcelable接口的实体类。

    // IMyAidlInterface.aidl
    package lennie.org.lennie.aidl;

    // Declare any non-default types here with import statements
    //这里需要引入回调接口,不然编译器找不到IMyCallback这个接口
    import lennie.org.lennie.aidl.IMyCallback;
    interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
        double aDouble, String aString);

        void onCallback(IMyCallback callback);
    }


    // IMyCallback.aidl
    package lennie.org.lennie.aidl;

    // Declare any non-default types here with import statements

    interface IMyCallback {

        void onSuccess(int i);
        void onError(String s);

    }

定义好接口后,需要“”Make Module“”下工程,gradle才会自动生成aidl文件

这里写图片描述

这里写图片描述

Service端定义

package lennie.org.lennie;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import lennie.org.lennie.aidl.IMyAidlInterface;
import lennie.org.lennie.aidl.IMyCallback;

/**
 * Created by win7 on 2017/7/26.
*/

public class MyService extends Service {

private static final String TAG = "MyService";
private RemoteCallbackList<IMyCallback> callbackList = new RemoteCallbackList<IMyCallback>();

//声明aidl接口
private IMyAidlInterface.Stub mIBinder = new IMyAidlInterface.Stub() {
    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
        Log.i(TAG, "anInt = " + anInt);
        Log.v(TAG, "aLong = " + aLong);
        Log.d(TAG, "aBoolean = " + aBoolean);
        Log.e(TAG, "aFloat = " + aFloat);
        Log.w(TAG, "aDouble = " + aDouble);
        onSuccessCallback();
        onErrorCallback();
    }

    @Override
    public void registerCallback(IMyCallback callback) throws RemoteException {
        if (callback != null) {
            Log.i(TAG,"registerCallback===>");
            callbackList.register(callback);
        }
    }

    @Override
    public void unregisterCallback(IMyCallback callback) throws RemoteException {
        if (callback != null) {
            callbackList.unregister(callback);
        }
    }

};

@Override
public IBinder onBind(Intent intent) {
    //返回定义好的IBinder
    return mIBinder;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.i(TAG,"onCreate == >");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG,"onStartCommand == >");
    return super.onStartCommand(intent, flags, startId);

}

private void onSuccessCallback() {
            //参照源码实现
            int beginBroadcast = callbackList.beginBroadcast();
            for (int i = 0; i < beginBroadcast; i++) {
                try {
                    callbackList.getBroadcastItem(i).onSuccess(1);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            callbackList.finishBroadcast();

}

private void onErrorCallback() {

            int beginBroadcast = callbackList.beginBroadcast();
            for (int i = 0; i < beginBroadcast; i++) {
                try {
                    callbackList.getBroadcastItem(i).onError("2");
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            callbackList.finishBroadcast();

}

@Override
public void onDestroy() {
    super.onDestroy();
    callbackList.kill();
}
}

客户端定义

package lennie.org.lennie;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.app.Activity;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import lennie.org.lennie.aidl.IMyAidlInterface;
import lennie.org.lennie.aidl.IMyCallback;

public class AIDLActivity extends Activity {


@BindView(R.id.tv)
TextView tv;
@BindView(R.id.tv_)
TextView tv_;

private IMyAidlInterface myAidlInterface;

//实现IMyCallback接口
private IMyCallback myCallback = new IMyCallback.Stub() {

    @Override
    public void onSuccess(final int i) throws RemoteException {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                tv.setText(" i = " + i);
            }
        });
    }

    @Override
    public void onError(final String s) throws RemoteException {
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                tv_.setText(" s = " + s);
            }
        });
    }
};

//使用ServiceConnection与Services进行通信
private ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //获取AIDL接口对象
        myAidlInterface = IMyAidlInterface.Stub.asInterface(service);

        try {
            myAidlInterface.registerCallback(myCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

        Toast.makeText(AIDLActivity.this,"绑定成功",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

        try {
            myAidlInterface.unregisterCallback(myCallback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        myAidlInterface = null;

        Toast.makeText(AIDLActivity.this,"解开绑定",Toast.LENGTH_SHORT).show();
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_aidl);
    ButterKnife.bind(this);

    Intent intent = new Intent(this,MyService.class);
    //在5.0及以上版本必须要加上这个
    intent.setPackage("service.hht.com.serviceapplication");
    bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);

}

@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(mServiceConnection);
}

@OnClick(R.id.bt)
public void onClick(View v) {

    if(myAidlInterface!=null){
        try {
            myAidlInterface.basicTypes(1,1,true, 1,2.2,"123");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }else{
        Toast.makeText(AIDLActivity.this,"服务未启动",Toast.LENGTH_SHORT).show();
    }
}


}

总结

aidl有大三步骤:

  • 定义AIDL接口

1、如果定义回调接口,需要既定使用import,把回调接口路径引入进来
2、使用“”Make Module“” 下工程,gradle才会自动生成aidl文件

  • Service暴露接口

1、声明mIBinder接口,通过mIBinder把接口暴露给客户端
2、如有回调使用RemoteCallbackList 进行接收和操作

  • 客户端绑定Service

1、使用ServiceConnection进行与Service绑定,使用定义好的AIDL文件来接受IBinder(IMyAidlInterface.Stub.asInterface(IBinder))
2 、如有回调则实现回调函数

因这几天看到AIDL的接口,因此做此记录。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值