demo下载地址
https://download.csdn.net/download/u010672559/10610856
----------
概述:AIDL即跨进程通信
1.在main下面新建aidl文件
// IMyAidlInterface.aidl
package com.android.aidl;
// Declare any non-default types here with import statements
import com.android.aidl.bean.Person;
interface IMyAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void addPerson(in Person person);
}
注意:如果addPerson(in Person person)不需要传Parcelable类型的Person对象,则不需要相应的Person.aidl文件及导包操作
“AIDL服务只支持有限的数据类型,因此,如果用AIDL服务传递一些复杂的数据就需要做更一步处理。AIDL服务支持的数据类型如下:
Java的简单类型(int、char、boolean等)。不需要导入(import)。
String和CharSequence。不需要导入(import)。
List和Map。但要注意,List和Map对象的元素类型必须是AIDL服务支持的数据类型。不需要导入(import)。
AIDL自动生成的接口。需要导入(import)。
实现android.os.Parcelable接口的类。需要导入(import)。
其中后两种数据类型需要使用import进行导入,将在本章的后面详细介绍。
传递不需要import的数据类型的值的方式相同。传递一个需要import的数据类型的值(例如,实现android.os.Parcelable接口的类)的步骤略显复杂。除了要建立一个实现android.os.Parcelable接口的类外,还需要为这个类单独建立一个aidl文件,并使用parcelable关键字进行定义。”
2.如果是带实体且类型为Person implements Parcelable类型的则注意需要相应aidl新建实体的aidl文件,且注意导包
---------------
// Person.aidl
package com.android.aidl.bean;
//还要和声明的实体类在一个包里
parcelable Person;
-----------
package com.android.aidl.bean;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
private String mName;
public Person(String name) {
mName = name;
}
protected Person(Parcel in) {
mName = in.readString();
}
public static final Creator
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mName);
}
@Override
public String toString() {
return "Person{" +
"mName='" + mName + '\'' +
'}';
}
}
------------------
结构如下图所示
3.之后make project则会生成app\build\generated\source\aidl\debug\com\android\yxz\aidltest03\IMyAidlInterface.java文件,如果没有生成则会编译报错,根据相应的错误提示修改即可
4.之后将main下面的aidl文件拷贝到另一个工程下面,确保包名类名一致,然后同样make project生成相应的java文件
5.之后再工程A中启动工程B的bindservice,在工程A的ServiceConnection mConnection = new ServiceConnection()回调中可以得到binder,通过binder调用彼此aidl公共定义的方法就能调用到对方的方法了,当进程被杀死的时候会走onServiceDisconnected
---------
工程A
public class MainActivity extends AppCompatActivity {
public static final String TAG = "xiaozheng";
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt=(Button)findViewById(R.id.bt);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Log.d(TAG, "click");
mAidl.addPerson(new Person("yxz"));
}catch (Exception e){
e.printStackTrace();
Log.d(TAG, "e="+e);
}
}
});
bindService();
}
private void bindService() {
Intent serverIntent = new Intent();
serverIntent.setClassName("com.android.yxz.aidltestb", "com.android.yxz.aidltestb.MyAidlService");
bindService(serverIntent, mConnection, Context.BIND_AUTO_CREATE);
}
private IMyAidlInterface mAidl;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
Log.d(TAG, "onServiceConnected name="+name);
mAidl = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected name="+name);
mAidl = null;
}
};
}
---------
工程B的service
public class MyAidlService extends Service {
public static final String TAG = "xiaozheng";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "MyAidlService onCreate");
}
private IBinder mIBinder =new IMyAidlInterface.Stub(){
@Override
public void addPerson(Person person) throws RemoteException {
Log.d(TAG, "AidlTestB addPerson person="+person);
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mIBinder;
}
}
6.service记得在清单里面注册,且属性里面加以下属性,否则会报错Not allowed to bind to service Intent
7.点击button即工程A调用到了工程B的方法,即实现了跨进程通信的目的