android aidl的使用及demo

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的方法,即實現了跨進程通信的目的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章