溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android通過Service調(diào)用遠程接口—AIDL-進程間通信

發(fā)布時間:2020-07-24 04:36:09 來源:網(wǎng)絡(luò) 閱讀:746 作者:yangxiaoming123 欄目:移動開發(fā)

Andorid平臺中,各個組件運行在自己的進程中,他們之間是不能相互訪問的,但是在程序之間是不可避免的要傳遞一些對象,在進程之間相互通信。為了實現(xiàn)進程之間的相互通信,Andorid采用了一種輕量級的實現(xiàn)方式RPC(Remote Procedure Call 遠程進程調(diào)用)來完成進程之間的通信,并且Android通過接口定義語言(Andorid Interface Definition Language ,AIDL)來生成兩個進程之間相互訪問的代碼,例如,你在Activity里的代碼需要訪問Service中的一個方法,那么就可以通過這種方式來實現(xiàn)了。

   AIDL是Android的一種接口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預(yù)先定義的接口達到兩個進程內(nèi)部通信進程的目的. 如果需要在一個Activity中, 訪問另一個Service中的某個對象, 需要先將對象轉(zhuǎn)化成 AIDL可識別的參數(shù)(可能是多個參數(shù)), 然后使用AIDL來傳遞這些參數(shù), 在消息的接收端, 使用這些參數(shù)組裝成自己需要的對象。

   AIDL RPC機制是通過接口來實現(xiàn)的,類似Windows中的COM或者Corba,但他是輕量級的,客戶端和被調(diào)用實現(xiàn)之間是通過代理模式實現(xiàn)的,代理類和被代理類實現(xiàn)同一個接口Ibinder接口。

下面是實現(xiàn)Activity訪問Service例子的步驟:

一.創(chuàng)建.aidl文件

    AIDL使用簡單的語法來聲明接口,描述其方法以及方法的參數(shù)和返回值。這些參數(shù)和返回值可以是任何類型,甚至是其他AIDL生成的接口。重要的是必須導(dǎo)入導(dǎo)入除了內(nèi)建類型(例如:int,boolean等)外的任何其他類型,哪怕是這些類型是在與接口相同的包中。具體的要求如下:

  • JAVA基本數(shù)據(jù)類型不需要導(dǎo)入

  • String,List,MapCharSequence不需要導(dǎo)入

使用Eclipse的ADT插件創(chuàng)建一個BookInfo.aidl文件,該文件有4個方法:

setName(String name)設(shè)置圖書的書名,setPrice(int price)設(shè)置圖書的價格,setPublish(String pname)設(shè)置圖書的出版社和String display()顯示圖書的信息.

BookInfo.aidl文件

package com.android.aidl;   //BookInfo接口  interface BookInfo{            void setName(String name);      void setPrice(int price);      void ssetPublish(String pname);      //顯示圖書的信息      String display();  }

創(chuàng)建好BookInfo.aidl文件,系統(tǒng)會自動在gen目錄下生成Java接口文件BookInfo.java

Android通過Service調(diào)用遠程接口—AIDL-進程間通信

二.實現(xiàn)AIDL文件生成的JAVA接口

    AIDL會生成一個和.aidl文件同名的JAVA接口文件,該接口中有一個靜態(tài)抽象內(nèi)部類Stub,該類中聲明了AIDL文件中定義的所有方法,其中有一個重要的方法是asInterface(),該方法通過代理模式返回JAVA接口的實現(xiàn)我們可以定義一個實現(xiàn)類,BookImpl,該類繼承Stub類,實現(xiàn)我們定義的4個方法

package com.android.aidl;  import android.os.RemoteException;   public class BookInfoImpl extends BookInfo.Stub {      //聲明三個個變量      private int price;      private String name,pname;      //顯示書名,價格,出版社      public String display() throws RemoteException{          return "書名:"+name+";價格:"+price+";出版社:"+price;      }      @Override     //設(shè)置書名      public void setName(String name) throws RemoteException {          // TODO Auto          this.name= name;      }       @Override     //設(shè)置價格      public void setPrice(int price) throws RemoteException {          // TODO Auto-generated method stub          this.price = price;      }      @Override     //設(shè)置出版社      public void setPublish(String pname) throws RemoteException {          // TODO Auto          this.pname= pname;      }     }

三.向客戶端暴露接口

現(xiàn)在已經(jīng)實現(xiàn)了BookInfo接口,接下來要將該接口暴露給客戶端調(diào)用。一般通過定義一個Service來實現(xiàn),在Service的onBind()方法中返回該接口,當(dāng)我們綁定該接口時調(diào)用該方法。

package com.android.aidl;   import com.android.aidl.BookInfo.Stub;  import android.app.Service;  import android.content.Intent;  import android.os.IBinder;   public class RemoteService extends Service {      //聲明BookInfo接口      private Stub bookifo = new BookInfoImpl();      public IBinder onBind(Intent intent){          return bookifo;      }  }

四.在客戶端調(diào)用

定義一個Activity來綁定遠程Service,獲得BookInfo接口,通過RPC機制調(diào)用接口中的方法。

package com.android.aidl;   import android.app.Activity;  import android.app.Service;  import android.content.ComponentName;  import android.content.Intent;  import android.content.ServiceConnection;  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.Toast;   public class MainActivity extends Activity {      // 聲明IPerson接口      private BookInfo bookInfo;      // 聲明 Button      private Button btn;      // 實例化ServiceConnection      private ServiceConnection conn = new ServiceConnection() {          @Override         synchronized public void onServiceConnected(ComponentName name, IBinder service) {              // 獲得IPerson接口              bookInfo = BookInfo.Stub.asInterface(service);              if (bookInfo != null)                  try {                      // RPC 方法調(diào)用                      bookInfo.setName("Google Android SDK開發(fā)范例大全");                      bookInfo.setPrice(55);                      bookInfo.setPublish("人民郵電出版社");                      String msg = bookInfo.display();                      // 顯示方法調(diào)用返回值                      Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG)                              .show();                  } catch (RemoteException e) {                      e.printStackTrace();                  }          }           @Override         public void onServiceDisconnected(ComponentName name) {           }      };       @Override     public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          // 設(shè)置當(dāng)前視圖布局          setContentView(R.layout.main);          // 實例化Button          btn = (Button) findViewById(R.id.Button1);          //為Button添加單擊事件監(jiān)聽器          btn.setOnClickListener(new OnClickListener() {              @Override             public void onClick(View v) {                  // 實例化Intent                  Intent intent = new Intent();                  // 設(shè)置Intent Action 屬性                  intent.setAction("com.android.aidl.action.MY_REMOTE_SERVICE");                  // 綁定服務(wù)                  bindService(intent, conn, Service.BIND_AUTO_CREATE);              }          });      }  }

五.main.xml和AndroidManifest.xml文件

main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     >     <Button           android:text="遠程調(diào)用Service"           android:id="@+id/Button1"           android:layout_width="wrap_content"           android:layout_height="wrap_content"         /> </LinearLayout>

在AndroidManifest.xml文件16~20聲明Service

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"       package="com.android.aidl"       android:versionCode="1"       android:versionName="1.0">     <uses-sdk android:minSdkVersion="10" />      <application android:icon="@drawable/icon" android:label="@string/app_name">         <activity android:name=".MainActivity"                   android:label="@string/app_name">             <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="com.android.aidl.action.MY_REMOTE_SERVICE"/>             </intent-filter>     </service>     </application> </manifest>

效果圖:

Android通過Service調(diào)用遠程接口—AIDL-進程間通信


向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI