AIDL (Android Interface Definition Language )是一种IDL语言
AIDL 适用于进程间通信,并且与Service端多个线程并发的情况,如果只是单个线程 可以使用 Messenger ,如果不需要IPC 可以使用Binder
AIDL语法:基础数据类型都可以适用,List Map等有限适用。static field 不适用
第一步:AIDL接口文件,扩展名为.aidl,保存在src目录下
接口描述文件
1、对于Java编程语言的基本数据类型 (int, long, char, boolean等),String和CharSequence,集合接口类型List和Map,不需要import 语句。
2、如果有使用Object对象,需要该对象 implement Parcelable 接口,并且需要导入该接口包名+类名;
如果是primitive type 不需要这步。
3、定义方法名称。
4、所有的.aidl文件已经需要传递的对象接口需要在Service 与Client中各一份
名字是MyAIDLInterface.aidl
package com.example.aidlserver1;
interface MyAIDLInterface {
int getCount();
void setCount(int count);
}
第二步:在Service中实现.aidl 接口。实际实现的接口是在gen中自动生成的MyAIDLInterface.java的抽象内部类Stub
1、需要在配置文件Androidmanifest.xml文件中声明Service,并且添加intent-filter 节点 的action属性,
此属性一般可以使用 aidl的包名+文件名(因为该值在服务器与客户端一致)
2、需要实现MyAIDLInterface.aidl文件中定义的接口。
aidl文件是一个接口描述文件,会在gen中自动生成一个同名的MyAIDLInterface.java接口文件,该接口文件包含一个抽象类stub,其继承了android.os.Binder、实现IaidlData接口
故,我们实际需要实现的是Stub抽象类。
public class MyAIDLService extends Service {
private final static String TAG = "MyAIDLService";
private int mCount;
private MyAIDLInterface.Stub myBinder = new MyAIDLInterface.Stub() {
@Override
public int getCount() throws RemoteException {
//实现接口文件函数
return mCount;
}
@Override
public void setCount(int count) throws RemoteException {
//实现接口文件函数
mCount = count;
}
};
public void onCreate() {
//服务onCreate
mCount = 2;
Toast.makeText(this, "Service onCreate", Toast.LENGTH_SHORT).show();
super.onCreate();
}
public void onDestroy() {
Toast.makeText(this, "Service onDestroy", Toast.LENGTH_SHORT).show();
super.onDestroy();
}
public int onStartCommand(Intent intent, int flags, int startId) {
//
Toast.makeText(this, Integer.toString(mCount), Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
//客户端绑定服务
return myBinder;
}
}
第三步:服务注册
<service android:name=".MyAIDLService">
<intent-filter>
<action android:name="com.trinea.android.demo.remote.MyAIDLServiceAction" />
</intent-filter>
</service>
第四步:客户端,绑定Service ,并且获取aidl对象
新建一个包,名字是aidl文件的包名com.example.aidlserver1,然后将aidl文件拷贝到其下面
建立连接,使用Action属性定位需要的Service,actoin的属性的采用aidl文件的类名+包名(与服务一致),之前需要在服务中设置相同的action属性,否则找不到服务
package com.example.aidlclient1;
import com.example.aidlserver1.MyAIDLInterface; //导入aidl文件
public class MainActivity extends Activity implements OnClickListener {
private final static String TAG = "MainActivity";
private MyAIDLInterface binder = null;
private Button boundAIDLServiceBtn, getBoundAIDLServiceProBtn, unboundAIDLServiceBtn;
private ServiceConnection con = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder service) {
// 得到服务的绑定对象
binder = MyAIDLInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
Log.v(TAG, "onServiceDisconnected");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boundAIDLServiceBtn = (Button)findViewById(R.id.boundAIDLService);
unboundAIDLServiceBtn = (Button)findViewById(R.id.unboundAIDLService);
getBoundAIDLServiceProBtn = (Button)findViewById(R.id.getBoundAIDLServicePro);
boundAIDLServiceBtn.setOnClickListener(this);
unboundAIDLServiceBtn.setOnClickListener(this);
getBoundAIDLServiceProBtn.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()){
case R.id.boundAIDLService:{
Intent myAIDLServiceIntent = new Intent("com.trinea.android.demo.remote.MyAIDLServiceAction");
boolean result = bindService(myAIDLServiceIntent, con, Context.BIND_AUTO_CREATE);
if (!result) {
binder = null;
Toast.makeText(getApplicationContext(), "服务绑定失败。", Toast.LENGTH_SHORT).show();
}else{
Log.v(TAG, "bindService, success");
}
}
break;
case R.id.unboundAIDLService:{
if (binder != null) {
unbindService(con);
binder = null;
}
}
break;
case R.id.getBoundAIDLServicePro:{
try {
if (binder != null) {
binder.setCount(17);
Toast.makeText(getApplicationContext(), "Service count:" + binder.getCount(),
Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "请先绑定服务。", Toast.LENGTH_SHORT).show();
}
}catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
}
LOG
client:bindService, success
server:onCreate
server:onBind
client:onServiceConnected
server:setCount
server:getCount
server:onDestroy