android開發AIDL執行個體

來源:互聯網
上載者:User

            由於每個應用程式都運行在自己的進程空間,並且可以從應用程式UI運行另一個服務進程,而且經常會在不同的進程間傳遞對象。在Android平台,一個進程通常不能訪問另一個進程的記憶體空間。但是android提供了AIDL可以用來進程間資料傳遞。

         AIDL (Android Interface Definition Language) 是一種IDL 語言,用於產生可以在Android裝置上兩個進程之間進行處理序間通訊(interprocess communication, IPC)的代碼。如果在一個進程中(例如Activity)要調用另一個進程中(例如Service)對象的操作,就可以使用AIDL產生可序列化的參數。
    AIDL IPC機制是面向介面的,像COM或Corba一樣,但是更加輕量級。它是使用代理類在用戶端和實現端傳遞資料。

          下面通過一個執行個體來示範AIDL,因為是進程之間資料傳遞,所以這裡要使用建立android工程,一個是AIDL的服務端另一個是用戶端.

          服務端的實現步驟:

        1.建立.aidl檔案      IMyService.aidl

        

package cn.com.karl.aidl;import cn.com.karl.aidl.Person;interface IMyService {     void savePersonInfo(in Person person);     List<Person> getAllPerson();     String sayHello();}

     
       因為這裡用到了Peson對象,所以要建立一個person類。Person類,是一個序列化的類,這裡使用Parcelable 介面來序列化,是Android提供的一個比Serializable 效率更高的序列化類別。

       

public class Person implements Parcelable {    private String name;    private String telNumber;    private int age;    public Person() {}    public Person(Parcel pl){            name = pl.readString();            telNumber = pl.readString();            age = pl.readInt();    }    public String getName() {            return name;    }    public void setName(String name) {            this.name = name;    }    public String getTelNumber() {            return telNumber;    }    public void setTelNumber(String telNumber) {            this.telNumber = telNumber;    }    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.writeString(telNumber);            dest.writeInt(age);    }    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {            @Override            public Person createFromParcel(Parcel source) {                    return new Person(source);            }            @Override            public Person[] newArray(int size) {                    return new Person[size];            }    };}

           然後建立Person.aidl檔案,注意這裡的parcelable小寫。

         

package cn.com.karl.aidl;parcelable Person;

         上面的IMyService.aidl儲存以後會在gen的相應目錄下啟動產生如下代碼:

Binder

package cn.com.karl.aidl;public interface IMyService extends android.os.IInterface{/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements cn.com.karl.aidl.IMyService{private static final java.lang.String DESCRIPTOR = "cn.com.karl.aidl.IMyService";/** Construct the stub at attach it to the interface. */public Stub(){this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an cn.com.karl.aidl.IMyService interface, * generating a proxy if needed. */public static cn.com.karl.aidl.IMyService asInterface(android.os.IBinder obj){if ((obj==null)) {return null;}android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);if (((iin!=null)&&(iin instanceof cn.com.karl.aidl.IMyService))) {return ((cn.com.karl.aidl.IMyService)iin);}return new cn.com.karl.aidl.IMyService.Stub.Proxy(obj);}public android.os.IBinder asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION:{reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_savePersonInfo:{data.enforceInterface(DESCRIPTOR);cn.com.karl.aidl.Person _arg0;if ((0!=data.readInt())) {_arg0 = cn.com.karl.aidl.Person.CREATOR.createFromParcel(data);}else {_arg0 = null;}this.savePersonInfo(_arg0);reply.writeNoException();return true;}case TRANSACTION_getAllPerson:{data.enforceInterface(DESCRIPTOR);java.util.List<cn.com.karl.aidl.Person> _result = this.getAllPerson();reply.writeNoException();reply.writeTypedList(_result);return true;}case TRANSACTION_sayHello:{data.enforceInterface(DESCRIPTOR);java.lang.String _result = this.sayHello();reply.writeNoException();reply.writeString(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements cn.com.karl.aidl.IMyService{private android.os.IBinder mRemote;Proxy(android.os.IBinder remote){mRemote = remote;}public android.os.IBinder asBinder(){return mRemote;}public java.lang.String getInterfaceDescriptor(){return DESCRIPTOR;}public void savePersonInfo(cn.com.karl.aidl.Person person) throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);if ((person!=null)) {_data.writeInt(1);person.writeToParcel(_data, 0);}else {_data.writeInt(0);}mRemote.transact(Stub.TRANSACTION_savePersonInfo, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}public java.util.List<cn.com.karl.aidl.Person> getAllPerson() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();java.util.List<cn.com.karl.aidl.Person> _result;try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_getAllPerson, _data, _reply, 0);_reply.readException();_result = _reply.createTypedArrayList(cn.com.karl.aidl.Person.CREATOR);}finally {_reply.recycle();_data.recycle();}return _result;}public java.lang.String sayHello() throws android.os.RemoteException{android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();java.lang.String _result;try {_data.writeInterfaceToken(DESCRIPTOR);mRemote.transact(Stub.TRANSACTION_sayHello, _data, _reply, 0);_reply.readException();_result = _reply.readString();}finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_savePersonInfo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_getAllPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);static final int TRANSACTION_sayHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);}public void savePersonInfo(cn.com.karl.aidl.Person person) throws android.os.RemoteException;public java.util.List<cn.com.karl.aidl.Person> getAllPerson() throws android.os.RemoteException;public java.lang.String sayHello() throws android.os.RemoteException;}

      因為sub類實現了Binder介面,所以以後會使用這個類。

         2.實現service類
         

public class RemoteService extends Service {    private LinkedList<Person> personList = new LinkedList<Person>();        @Override    public IBinder onBind(Intent intent) {            return mBinder;    }    private final IMyService.Stub mBinder = new IMyService.Stub(){            @Override            public void savePersonInfo(Person person) throws RemoteException {                    if (person != null){                            personList.add(person);                    }            }            @Override            public List<Person> getAllPerson() throws RemoteException {                    return personList;            }@Overridepublic String sayHello() throws RemoteException {// TODO Auto-generated method stubreturn "歡迎你通過AIDL訪問伺服器端";}    };}

         3.用戶端實現步驟:

          首先建立一個項目,把服務端的

             包和類一起拷貝到用戶端項目中。因為用戶端要和服務端通訊,必須要使用同一個aidl。

         然後構造用戶端的activity類:

       

public class RemoteClientActivity extends Activity {    /** Called when the activity is first created. */private TextView textHello,textPerson;private IMyService myService;private Button btnSave;private Button btnGet;private static Boolean mIsRemoteBound=false;private ServiceConnection conn=new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubmyService=null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubmyService=IMyService.Stub.asInterface(service);try {textHello.setText(myService.sayHello());} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                textHello=(TextView) this.findViewById(R.id.textHello);        btnSave=(Button) this.findViewById(R.id.btnSave);        btnGet=(Button) this.findViewById(R.id.btnGet);        textPerson=(TextView) this.findViewById(R.id.textPerson);        if(mIsRemoteBound){        unbindService(conn);        }else{        Intent intent=new Intent("cn.com.karl.aidl.RemoteService");        bindService(intent, conn, BIND_AUTO_CREATE);        }        mIsRemoteBound = !mIsRemoteBound;        btnSave.setOnClickListener(new OnClickListener() {          private int index = 0;@Overridepublic void onClick(View v) {// TODO Auto-generated method stub   Person person = new Person();                   index = index + 1;                   person.setName("Person" + index);                   person.setAge(20);                   person.setTelNumber("123456");                    try {                   myService.savePersonInfo(person);                   } catch (RemoteException e) {                           e.printStackTrace();                   } }});        btnGet.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub  List<Person> list = null;                   try {                          list = myService.getAllPerson();                  } catch (RemoteException e) {                          e.printStackTrace();                  }                   if (list != null){                          StringBuilder text = new StringBuilder();                          for(Person person : list){                                  text.append("\n連絡人:");                                  text.append(person.getName());                                  text.append("\n             年齡:");                                  text.append(person.getAge());                                  text.append("\n 電話:");                                  text.append(person.getTelNumber());                          }                          textPerson.setText(text);                  }else {                          Toast.makeText(RemoteClientActivity.this, "得到資料出錯",                                          Toast.LENGTH_SHORT).show();                  } }});    }}

              最後不要忘記註冊service:

           

  <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service android:name=".RemoteService">            <intent-filter >                <action android:name="cn.com.karl.aidl.RemoteService"></action>            </intent-filter>        </service>    </application>

           啟動service的時候使用了隱士意圖。

          運行服務端工程.

        

         服務端已經啟動,然後運行用戶端工程:

        

         OK,已經從服務端得到了資料,第一句話就是從服務端得到的,下面看看,傳遞對象和擷取對象與服務端。

          點擊新增連絡人...,然後點擊擷取連絡人按鈕:

          

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.