Android學習之跨進程通信安卓接口定義語言AIDL(二)

接着剛剛的一篇講下使用AIDL傳遞對象的過程,AIDL在不導入其他包的情況下支持如下幾種數據類型:

1. 基本數據類型(boolean、char、byte、int、long、float、double),注意:不支持short

2. String和CharSequence

3. List和Map

4. Parcelable:

傳遞對象必須要實現序列化,ADIL中序列化對象的流程如下:

1)序列化對象

2)建立對象的.aidl文件,名稱要一樣

3)建立.aidl文件,手動導入對象,聲明對象是in還是out

接上一篇,看下工程結構,IDemoAidlInterface大家不用管,是上一篇的內容:

先看下怎麼序列化對象,首先創建Person類,實現Parcelable接口,具體方法怎麼使用看註釋

/**
 * 序列化
 *
 * @author yuzhentao
 */
public class Person implements Parcelable {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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 String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /**
     * 內容接口描述,默認返回0就可以
     *
     * @return int
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 將對象序列化爲一個Parcel對象
     * 將類的數據寫入外部提供的Parcel中,打包需要傳遞的數據到Parcel容器保存,以便從Parcel容器獲取數據
     *
     * @param dest:Parcel
     * @param flags:int
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    protected Person(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }

    /**
     * 實例化靜態內部對象CREATOR實現接口Parcelable.Creator
     */
    public static final Creator<Person> CREATOR = new Creator<Person>() {
        /**
         * 從Parcel容器中讀取傳遞數據值,封裝成Parcelable對象返回邏輯層
         * @param in:Parcel
         * @return Person
         */
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        /**
         *創建一個類型爲<T>,長度爲size的數組,供外部類反序列化本類數組使用
         * @param size:int
         * @return Person[]
         */
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

}
然後建立對象的.aidl文件,名稱要一樣,寫法是

package yuzhentao.aidldemo;

//必須這樣寫
parcelable Person;
然後建立.aidl文件,手動導入對象,聲明對象是in還是out,這裏切記一定要手動導入一下

package yuzhentao.aidldemo;

//手動導入
import yuzhentao.aidldemo.Person;

interface IParcelableAidlInterface {

    //一定要帶上in或者out,告訴這個Person是輸入還是輸出的
    List<Person> add(in Person person);

}

接着就是修改Service的內容了,將接口更改一下即可,然後返回ArrayList<Person>

/**
 * Aidl服務
 *
 * @author yuzhentao
 */
public class IDemoAidlService extends Service {

    private ArrayList<Person> personList;

    /**
     * 當客服端綁定到服務端時會執行
     *
     * @param intent:Intent
     * @return IBinder
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
//        return iBinder;
        personList = new ArrayList<>();
        return iBinderPerson;
    }

//    private IBinder iBinder = new IDemoAidlInterface.Stub() {
//        @Override
//        public int add(int num1, int num2) throws RemoteException {
//            Log.e("yzt", "收到遠程請求,輸入的參數是:" + num1 + "和" + num2);
//            return num1 + num2;
//        }
//    };

    private IBinder iBinderPerson = new IParcelableAidlInterface.Stub() {
        @Override
        public List<Person> add(Person person) throws RemoteException {
            personList.add(person);
            return personList;
        }
    };

}

服務端準備完畢,接着將這些文件包括複製到客戶端,包名一定要一樣,看下客戶端的結構,同樣請無視IDemoAidlInterface


客戶端同樣將接口修改一下,點擊時實例化一個ArrayList<Person>,通過接口的方法傳遞到服務端,打印Log看下結果

/**
 * 客戶端
 * 獲取服務端
 * .aidl必須和服務端的一樣,包括包名,負責編譯不通過
 * 如果有序列化對象,連同包名也必須一樣
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    //    private IDemoAidlInterface iDemoAidlInterface;
    private IParcelableAidlInterface iParcelableAidlInterface;
    /**
     * 服務連接接口
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//連接服務時執行,ComponentName是bindService()指定的,IBinder是服務端的onBind()返回的
//            iDemoAidlInterface = IDemoAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了遠程的服務的代理
            iParcelableAidlInterface = IParcelableAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了遠程的服務的代理
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//斷開服務時執行
//            iDemoAidlInterface = null;
            iParcelableAidlInterface = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        bindService();//綁定服務
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);//解綁服務
    }

    private void initView() {
//        final EditText etNum1 = (EditText) findViewById(R.id.edittext_num1_activity_main);
//        final EditText etNum2 = (EditText) findViewById(R.id.edittext_num2_activity_main);
//        final EditText etResult = (EditText) findViewById(R.id.edittext_result_activity_main);
        findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                int num1 = Integer.parseInt(etNum1.getText().toString());
//                int num2 = Integer.parseInt(etNum2.getText().toString());
//                String result;
//                try {
//                    result = iDemoAidlInterface.add(num1, num2) + "";//調用遠程的服務
//                    etResult.setText(result);
//                } catch (RemoteException e) {
//                    e.printStackTrace();
//                    etResult.setText("發生錯誤");
//                }
                try {
                    ArrayList<Person> personList = (ArrayList<Person>) iParcelableAidlInterface.add(new Person("yuzhentao", 25));
                    Log.e("yzt", personList.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 綁定服務
     * alt+command+m:提取方法
     */
    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("yuzhentao.aidldemo", "yuzhentao.aidldemo.IDemoAidlService"));//顯式Intent
        bindService(intent, conn, Context.BIND_AUTO_CREATE);//綁定服務
    }

}
03-14 14:38:49.319 31540-31540/yuzhentao.aidldemoclient E/yzt: [Person{name='yuzhentao', age=25}]

這裏沒有效果圖,在此感謝下慕課網

Demo地址:http://download.csdn.net/detail/qq_23940659/9467044

發佈了36 篇原創文章 · 獲贊 11 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章