AIDL是一个缩写,全称是Android Interface Definition Language,Android接口定义语言。设计这门语言的目的是为了实现进程间通信。因为两个进程无法直接通信,需要Android系统底层间接通信。
Android中三种通信方式和使用场景:
AIDL IPC 多个应用程序 多线程
Binder 只有IPC 没有多线程 多个应用程序
Messenger 只有IPC 没有多线程
要学习AIDL之前,你肯定要学会两点:
1.关于Android中service相关的知识
2.关于Android中序列化的相关知识
AIDL传递的数据类型:
1.基本数据类型(除short外)
2.String,CharSequence
3.List,map
4.Parcelable
AIDL基本语法:
1.语法和java的接口相似
2.AIDL只支持方法,能定义静态成员
3.AIDL运行方法有任何类型的参数和返回值
4.除默认的类型外,均需要导包
首先创建一个和java同级的Folder;如图:
然后创建一个后缀为.aidl 的文件,如图:
*aidl的包名要和java下的包名要一致,aidl的文件名你可以自定义
一.传递基本数据
计算两个数的和,要在服务端实现方法,在客户端计算它们的和:
在服务端的aidl文件中:里面默认的方法你可以留下也可以删除;
// IMyAidlInterface.aidl
package com.example.myapplication;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
int add(int num1, int num2);
}
然后接下来需要一个Service暴露一个接口给客户端,创建一个Service;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
private IBinder iBinder=new IMyAidlInterface.Stub(){
@Override
public int add(int num1, int num2) throws RemoteException {
Log.e("TAG", "收到了---------- "+num1+"--------"+num2);
return num1 + num2;
}
};
}
然后在客户端,我是同一个项目里面创建一个Module,作为客户端,然后同样创建一个和服务端一样的和java同级的Floder和aidl文件,包名和类名要和服务端一致;
// IMyAidlInterface.aidl
package com.example.myapplication;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
int add(int num1, int num2);
}
内容和服务端一样,你可以拷贝过来;然后创建一个Activity,和服务端的Service进行通信;
public class MainActivity extends Activity {
@BindView(R.id.edit_num1)
EditText editNum1;
@BindView(R.id.edit_num2)
EditText editNum2;
@BindView(R.id.edit_result)
EditText editResult;
@BindView(R.id.btn)
Button btn;
@BindView(R.id.btn1)
Button btn1;
IMyAidlInterface iMyAidlInterface;
private ServiceConnection myconn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
iMyAidlInterface = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
bingServiceTest();
}
@OnClick(R.id.btn)
public void onViewClicked() {
int num1 = Integer.parseInt(editNum1.getText().toString());
int num2 = Integer.parseInt(editNum2.getText().toString());
try {
int res = iMyAidlInterface.add(num1, num2);
editResult.setText(res + "");
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void bingServiceTest() {
Intent intent = new Intent();
//第一个参数是你的包名,第二个是服务端的包名.你的Service名
intent.setComponent(new ComponentName("com.test1221.lsntest0311", "com.test1221.lsntest0311.MyService"));
bindService(intent, myconn, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
}
activity_main的效果如下,布局我就不展示了,自己放按钮等其他的;
然后运行,首先你要启动你的服务端,然后在启动你的客户端,结果如下:
二.传递对象,自定义类型
步骤是一样,在服务端首先创建一个Person类实现序列化;
public class Person implements Parcelable{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(Parcel source) {
this.name=source.readString();
this.age=source.readInt();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public static final Creator<Person> CREATOR=new Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
然后在aidl Floder下创建,如图:
// IMyAidlPerson.aidl
package com.test1221.lsntest0311;
// Declare any non-default types here with import statements
import com.test1221.lsntest0311.Person;
interface IMyAidlPerson {
List<Person> add( in Person person);
}
// IMyAidlPerson.aidl
package com.test1221.lsntest0311;
parcelable Person;
然后在Service里面:
public class PersonService extends Service {
private ArrayList<Person> persons;
@Override
public IBinder onBind(Intent intent) {
persons=new ArrayList<Person>();
return binder;
}
private Binder binder=new IMyAidlPerson.Stub(){
@Override
public List<Person> add(Person person) throws RemoteException {
persons.add(person);
return persons;
}
};
}
就下来是在客户端,复制过来就行;内容一样的;
也要把Person类复制过来,包名要一样;
然后在Activity里面实现:
package com.fjx.test1221.aidlclient;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import com.fjx.test1221.lsntest0311.IMyAidlInterface;
import com.fjx.test1221.lsntest0311.IMyAidlPerson;
import com.fjx.test1221.lsntest0311.Person;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class MainActivity extends Activity {
@BindView(R.id.edit_num1)
EditText editNum1;
@BindView(R.id.edit_num2)
EditText editNum2;
@BindView(R.id.edit_result)
EditText editResult;
@BindView(R.id.btn)
Button btn;
IMyAidlInterface iMyAidlInterface;
IMyAidlPerson aidlPerson;
@BindView(R.id.btn1)
Button btn1;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
aidlPerson=IMyAidlPerson.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
aidlPerson = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
bingServiceTest();
}
@OnClick(R.id.btn1)
public void onViewClicked1() {
try {
List<Person> list= aidlPerson.add(new Person("张三",26));
Log.e("list", list.toString() );
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void bingServiceTest() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.test1221.lsntest0311", "com.test1221.lsntest0311.PersonService"));
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection );
}
}
view视图就一个按钮,我就不展示了,运行:
好了,基本就讲完了,自定义类型里面的 in out inout你们可以搜一下其他文章看看。