Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android基本功:跨進程調用Services(AIDL Service)

Android基本功:跨進程調用Services(AIDL Service)

編輯:關於Android編程

一、AIDL Service簡介

Android系統中,各個應用都運行在自己的進程中,進程之間一般無法直接進行通信,為了實現進程通信(interprocess communication,簡稱IPC),Android提供了AIDL Service;

二、與本地Service不同

  • 本地Service:直接把IBinder對象本身傳遞給客戶端的ServiceConnection的onServiceConnected方法的第二個參數;

  • 遠程Service:只將IBinder對象的代理傳給客戶端的ServiceConnection的onServiceConnected方法的第二個參數;

    三、AIDL文件

    Android需要AIDL(Android Interface Definition Language)來定義遠程接口,這種接口定義語言並不是一種真正的變成語言,只是定義兩個進程之間的通信接口;

    與Java接口相似,但是存在如下幾點差異:

    • AIDL定義接口的源代碼必須以.aidl結尾;

    • AIDL用到的數據類型,除了基本類型、String、List、Map、CharSequence之外,其它類型全部都需要導包,即使它們在同一個包中也需要導包;

      四、使用AIDL的步驟(詳細代碼可見AIDLService和AIDLClient項目)

      1.創建AIDL文件

      package com.example.aidlservice; 
       
      interface ICat { 
          String getColor(); 
          double getWeight(); 
      } 
      定義好AIDL文件後,ADT工具會自動在gen/com/example/aidlservice/目錄下生成一個ICat.java接口,該類內部包含一個Stub內部類,實現了IBinder,ICat兩個接口,這個Stub類會作為遠程Service回調類;

      2.將接口暴露給客戶端

      package com.example.aidlservice; 
      import java.util.Timer; 
      import java.util.TimerTask; 
      import com.example.aidlservice.ICat.Stub; 
      import android.app.Service; 
      import android.content.Intent; 
      import android.os.IBinder; 
      import android.os.RemoteException; 
       
      public class AidlService extends Service { 
          String[] colors = new String[] { "紅色", "黃色", "黑色" }; 
          double[] weights = new double[] { 2.3, 3.1, 1.58 }; 
          private String color; 
          private double weight; 
          private CatBinder catBinder; 
          Timer timer = new Timer(); 
       
          @Override 
          public void onCreate() { 
              super.onCreate(); 
              catBinder = new CatBinder(); 
              timer.schedule(new TimerTask() { 
       
                  @Override    
                  public void run() { 
                      // 隨機地改變service組件內的color,weight屬性的值 
                      int rand = (int) (Math.random() * 3);   
                      color = colors[rand]; 
                      weight = weights[rand]; 
                      System.out.println("---------" + rand); 
                  } 
              }, 0, 800)}; 
       
          @Override 
          public IBinder onBind(Intent arg0) { 
              /**   
              * 返回CatBinder對象,在綁定本地Service情況下, 
              * 該catBinder會直接傳給客戶端的ServiceConnected對象的ServiceConnected 
              * ()方法的第二個參數;在綁定遠程Service的情況下  
              * ,只將catBinder對象的代理傳給客戶端的ServiceConnected對象的ServiceConnected()方法的第二個參數 
              */ 
              return catBinder; 
          } 
       
          @Override 
          public void onDestroy() { 
              timer.cancel(); 
          } 
       
          /**    
          * 繼承Stub,也就是實現了ICat接口,並實現了IBinder接口 
          *  
          * @author pengcx 
          * 
          */ 
          public class CatBinder extends Stub { 
              @Override 
              public String getColor() throws RemoteException { 
                  return color; 
              } 
       
          @Override 
              public double getWeight() throws RemoteException { 
                  return weight; 
              } 
          } 
      } 

      在AndroidManifext.xml文件中配置該Service;

       
           
               
           
        

      3.客戶端訪問AIDLService

      將Service端的AIDL文件復制到客戶端中,注意要在相同的包名下。

      package com.example.aidlclient; 
       
      import com.example.aidlservice.ICat; 
      import android.os.Bundle; 
      import android.os.IBinder; 
      import android.os.RemoteException; 
      import android.view.View; 
      import android.view.View.OnClickListener; 
      import android.widget.Button; 
      import android.widget.EditText; 
      import android.app.Activity; 
      import android.app.Service; 
      import android.content.ComponentName; 
      import android.content.Intent; 
      import android.content.ServiceConnection; 
       
      public class AidlClient extends Activity { 
          private ICat catService; 
          private Button getButton; 
          private EditText colorEditText, weightEditText; 
       
          private ServiceConnection conn = new ServiceConnection() { 
              @Override 
              public void onServiceDisconnected(ComponentName name) { 
                  catService = null; 
              } 
       
              @Override 
              public void onServiceConnected(ComponentName name, IBinder service) { 
                  // 獲取遠程Service的onBinder方法返回的對象代理 
                  catService = ICat.Stub.asInterface(service); 
              } 
          }; 
       
          @Override 
          protected void onCreate(Bundle savedInstanceState) { 
              super.onCreate(savedInstanceState); 
              setContentView(R.layout.activity_aidl_client); 
       
              getButton = (Button) findViewById(R.id.getbutton); 
              colorEditText = (EditText) findViewById(R.id.coloredittext); 
              weightEditText = (EditText) findViewById(R.id.weightedittext); 
       
              // 創建所需要綁定的Service的Intent 
              Intent intent = new Intent(); 
              intent.setAction("org.crazyit.aidl.action.AIDL_SERVICE"); 
              // 綁定遠程的服務 
              bindService(intent, conn, Service.BIND_AUTO_CREATE); 
                   
              getButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
          // 獲取並顯示遠程service的狀態 
          try { 
              colorEditText.setText(catService.getColor()); 
              weightEditText.setText(catService.getWeight() + ""); 
          } catch (RemoteException e) { 
              e.printStackTrace(); 
          } 
      } 
             }); 
          } 
       
          @Override 
          protected void onDestroy() { 
              super.onDestroy(); 
              // 解除綁定 
              this.unbindService(conn); 
          } 
      } 

      錯誤:java.lang.SecurityException: Binder invocation to an incorrect interface。在使用上請注意,服務端與客戶端都要有相同的接口(使用到的),這裡的“相同”是指完全相同,包括包名,也就是說要在不同工程下建立相同的包名。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved