一篇理解AIDL很好的文章

來源:互聯網
上載者:User

Android Service在工作中也用的很多,但是AIDL就用的很少了,感覺也很生疏,之前在公司也有同事做過技術講座,而且也看過一些技術文章,但是感覺依然朦朦朧朧的。現在從事教學工作後,把AIDL又看了一遍,發現其實並不用理解的那麼複雜,其實很簡單的一個RPC(IPC)機制。

使用AIDL涉及到的前提是:需要跟其他應用的Service進行資料交換或者是方法調用。(也就是遠程操作其他Service)。否則如果沒有資料交換或方法調用,直接使用startService()即可;本地Service更加無需AIDL。

 

明確這個大前提後,來看AIDL所涉及的幾個知識點:

1.ServiceConnection介面:實現這個介面後可以實現Service串連狀態的回調方法onServiceConnected(ComponentName component, IBinder service)和onServiceDisconnected(ComponentName component)。

2.IBinder介面

3.Binder類:Binder可以想象成一個記憶體共用對象,這個對象只有方法暴露出來給用戶端調用。

4.Stub靜態內部類:其實就是繼承了Binder和實現了自己定義的AIDL介面的一個類(所謂的代理),就是一個實現了自己定義的介面的一個Binder。

5.實現了Parcelable序列化介面的自訂Java Bean:如果傳輸簡單資料,根本沒必要。(順便說兩句:1.要想把資料存放區到磁碟或者是通過網路傳輸,一定要序列化;2.最為經常使用的Bundle其實就是一個Parcelable,可以通過Bundle來理解Parcelable)

使用AIDL要注意的地方:

1.檔案名稱字一定要以.aidl結尾

2..aidl檔案的包名很重要,Service端和調用端包名一定要保持一致。

 

先上一張圖,說明整個調用過程和遠端程序呼叫的原理:

下面貼出工程代碼結構圖:

下面上代碼:

1.IPerson.aidl檔案:

[java]
  1. package com.wenix.service.aidl;
  2. /**
  3. *除了基本類型,String,List,Map,CharSequence以外,其他類型一定要導包,即時是同一包下。
  4. */
  5. import com.wenix.service.aidl.Person;
  6. interface IPerson{
  7. Person getPerson(in int id);
  8. }

2.Person.aidl檔案:(用來聲明序列化對象)

[java]
  1. package com.wenix.service.aidl;
  2. /**
  3. *這裡聲明Person類型的時候是小寫parcelable
  4. */
  5. parcelable Person;


3.PersonService.java檔案:(定義提供服務的Service,記住一定要在AndroidMenifest.xml檔案中註冊)

[java]
  1. package com.wenix.androidaidl;
  2. import com.wenix.service.aidl.IPerson;
  3. import com.wenix.service.aidl.Person;
  4. import android.app.Service;
  5. import android.content.Intent;
  6. import android.os.IBinder;
  7. import android.os.RemoteException;
  8. public class PersonService extends Service {
  9. //由於是遠程Service,所以用戶端肯定不能使用顯示Intent來啟動Service,所以必須提供ACTION。
  10. public static final String AIDL_ACTION = "com.wenix.intent.action.AIDL_ACTION";
  11. private PersonBinder personBinder;
  12. /**
  13. * 這裡繼承了自動產生的Stub靜態內部類,並提供了介面方法的實現。
  14. * @author wenix
  15. */
  16. public class PersonBinder extends IPerson.Stub{
  17. @Override
  18. public Person getPerson(int id) throws RemoteException {
  19. //這裡只返回了一個簡單的自訂對象,其實原理相同,任何複雜物件只要序列化了,都可以返回
  20. return new Person(id, "wenix", "wenix");
  21. }
  22. }
  23. @Override
  24. public IBinder onBind(Intent intent) {
  25. //此處返回提供給用戶端的Binder對象(記憶體共用對象)
  26. return personBinder;
  27. }
  28. @Override
  29. public void onCreate() {
  30. super.onCreate();
  31. //進行資料初始化
  32. personBinder = new PersonBinder();
  33. }
  34. }


4.用戶端代碼:(綁定遠程Service,然後擷取Binder對象,然後進行資料交換和方法調用)

[java]
  1. package com.wenix.androidclient;
  2. import android.app.Activity;
  3. import android.content.ComponentName;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.ServiceConnection;
  7. import android.os.Bundle;
  8. import android.os.IBinder;
  9. import android.os.RemoteException;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.view.ViewGroup.LayoutParams;
  14. import android.widget.Button;
  15. import android.widget.LinearLayout;
  16. import android.widget.TextView;
  17. import com.wenix.service.aidl.IPerson;
  18. public class MainActivity extends Activity {
  19. private static final String TAG = "MainActivity";
  20. private class PersonServiceConnection implements ServiceConnection{
  21. @Override
  22. public void onServiceConnected(ComponentName cmp, IBinder service) {
  23. //用戶端在這個回調方法中獲得Binder對象
  24. IPerson p = IPerson.Stub.asInterface(service);
  25. try {
  26. //這裡調用AIDL規定的介面來擷取資料
  27. Log.i(TAG, p.getPerson(1).toString());
  28. } catch (RemoteException e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. @Override
  33. public void onServiceDisconnected(ComponentName name) {
  34. }
  35. }
  36. @Override
  37. public void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. //介面採用動態布局
  40. LinearLayout ll = new LinearLayout(this);
  41. ll.setOrientation(LinearLayout.VERTICAL);
  42. ll.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
  43. LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
  44. Button btn = new Button(this);
  45. btn.setLayoutParams(params);
  46. btn.setText("擷取Service資料");
  47. btn.setOnClickListener(new OnClickListener() {
  48. @Override
  49. public void onClick(View v) {
  50. //啟動相應的Service,由於是遠程Service,所以不能使用顯示Intent
  51. Intent service = new Intent("com.wenix.intent.action.AIDL_SERVICE");
  52. PersonServiceConnection conn = new PersonServiceConnection();
  53. bindService(service, conn, Context.BIND_AUTO_CREATE);
  54. }
  55. });
  56. TextView tv = new TextView(this);
  57. tv.setLayoutParams(params);
  58. ll.addView(btn);
  59. ll.addView(tv);
  60. setContentView(ll);
  61. }
  62. }

 

工程徹底完成,然後我們運行後點擊Button,就可以看到擷取的資料:

只需掌握整個流程,AIDL就可以很容易的使用。後期會加入一些使用AIDL的具體執行個體。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.