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<Person> CREATOR = new Creator<Person>() {
@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
<service android:name=".MyAidlService"
android:exported="true"/>
7.點擊button即工程A調用到了工程B的方法,即實現了跨進程通信的目的