简略地翻译一遍谷歌的教程,加深自己的理解。。。
AIDL(Android Interface Definition Language)用于来自不同应用的客户端访问service进行进程数据交换(IPC)
#创建一个AIDL接口的步骤:
- 创建一个.aidl文件
- 实现接口
- 暴露接口给客户端
##创建一个.aidl文件
.aidl文件的语法使用的是java语法,但做了一些限制,每一个.aidl文件都只定义一个接口,并且只能声明接口和抽象方法
.aidl文件支持以下数据类型:
- 所有的java基本类型(如int,long,byte,double,char,boolean等)
- String
- CharSequence
- List
List中的元素数据类型必须是以下三种之一
- List集合支持的数据类型
- 其他AIDL生成的接口
- 实现了Parcelable接口
- Map
Map中的元素数据类型要求同上面的List.
上面未列出来的类型在使用的时候必须使用import声明导入,即使这个类和.aidl文件在同一个包下。
在定义一个service接口的时候需要注意的是:
- 方法可以没有参数,返回值可有可无
- 所有非基本数据类型的参数都需要指示出数据离开的方向(in/out/inout)
- 所有.aidl文件中的注释都包含在生成的IBinder接口中(声明在import和package语句之前的注释除外)
- 只能声明抽象方法,不能定义静态常量
我创建了如下的MyAidl.aidl文件
1 2 3 4 5 6 7 8 9
| package com.diaoslin.androidlearn.service;
interface MyAidl { void showNotification(); void cancelNotification(); }
|
- ##实现接口
当建立好.aidl文件后,Android SDK Tool会自动生成相应的.java文件,使用Android Studio需要在build.gradle文件中指定AIDL目录,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| android { compileSdkVersion 17 buildToolsVersion "18.1.0"
defaultConfig { minSdkVersion 7 targetSdkVersion 16 } sourceSets { main { aidl.srcDirs = ['src/main/java'] } } }
|
生成的java接口类中,包含所有在.aidl文件中声明的方法,还有一个Stub抽象子类。
要实现.aidl文件中声明的接口,需要继承这个Stub子类,并且实现所有.aidl中声明的方法,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| MyAidl.Stub mBinder = new MyAidl.Stub() { @Override public void showNotification(){ Log.d("mBinder", "showNotification"); Intent i = new Intent(AidlService.this, AidlActivity.class); PendingIntent pi = PendingIntent.getActivity(AidlService.this, 0, i, 0);
Notification notification = new Notification.Builder(AidlService.this) .setAutoCancel(true) .setSmallIcon(R.drawable.ic_launcher) .setWhen(System.currentTimeMillis()) .setContentTitle("标题") .setTicker("显示通知成功") .setContentIntent(pi) .setContentText("消息内容") .build(); mNotificationManager.notify(NOTIFICATION_ID, notification); }
@Override public void cancelNotification() throws RemoteException { mNotificationManager.cancel(NOTIFICATION_ID); } };
|
在service的onBind()方法中返回.Stub对象,在客户端中,在ServiceConnect对象的onServiceConnected()方法中
调用MyAidl.Stub.asInterface(service)
这个Sub子类冲还包含一个比较重要的方法:asInterface()
这个方法通常在ServiceConnecttion对象的onServiceConnected()方法中调用,返回一个MyAidl.Stub对象
1 2 3 4 5 6 7 8 9 10 11 12 13
| ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mMyAidl = MyAidl.Stub.asInterface(service); Log.d("mConnection", "onServiceConnected"); }
@Override public void onServiceDisconnected(ComponentName name) { mMyAidl = null; Log.d("mConnection", "onServiceDisconnected"); } };
|
当客户端调用bindService()绑定Service后,可以通过ServiceConnection对象的onServiceConnected()方法获得MyAidl.Stub对象
#在IPC中传递对象
如果需要在进程之间通过IPC接口传递对象,那么这个对象的class必须实现了Parcelable接口
#参考资料:
Author:
linroid
Permalink:
http://linroid.com/2013/10/10/2013-10-10-android-aidl/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Slogan:
Do you believe in DESTINY?