Android學習筆記二十六.跨進程調用Service(AIDL Service),androidaidl

來源:互聯網
上載者:User

Android學習筆記二十六.跨進程調用Service(AIDL Service),androidaidl
跨進程調用Service(AIDL Service)一、AIDL Service1.什麼是AIDL Service?    AIDL,即Android Interface Definition Language.是Android用於定義遠程介面,AIDL介面定義語言的文法比較簡單,這種介面定義語言並不是真正的程式設計語言,它只是定義兩個進程之間的通訊介面。AIDL的文法與Java介面很相似,但存在如下幾點差異:(1)AIDL定義介面的原始碼必須以.aidl結尾;(2)AIDL介面中用到資料類型,除了基本類型、String、List、Map、CharSequence之外,其他類型全部都需要導包,即使他們在同一個包中也需要導包。    在Android系統中,由於各個應用程式都是運行在自己的進程中(啟動一個應用即啟動一個進程),進程之間一般無法直接進行資料交換。所以,為了實現進程之間的通訊(interprocess communiocation,簡稱IPC),Android提供了AIDL Service。2.遠程Service    與本地Service相對應的是遠程Service,即一個應用程式(進程)可以訪問另一個應用程式的Service組件前者我們稱之為用戶端、後者為服務端,而用戶端訪問服務端就是通過AIDL介面實現彼此間通訊的。通過之前幾篇文章我們知道,用戶端訪問Service時,Android並不是直接返回Service對象給用戶端,而是將Service的代理對象(IBinder對象)通過Service的onBind()方法返回給用戶端,因此,Android的AIDL遠程介面的實作類別就是那個IBinder實作類別。當用戶端擷取了遠程Service的IBinder對象的代理之後,用戶端進程就可通過該IBinder對象去回調遠程Service的屬性或方法,從而實現進程間的通訊。3.Service返回的IBinder對象    當訪問者(用戶端)調用bindService()方法來綁定與啟動指定的Service,對於綁定本地Service還是綁定遠程Service,Service返回的IBinder對象是有所區別的。(1)綁定本地Service:本地Service的onBind()方法會直接把IBinder對象本身傳給用戶端的ServiceConnection對象的onServiceConnected方法的第二個參數;(2)綁定遠程Service:遠程Service的onBind()方法只是將IBinder對象的代理傳給用戶端的ServiceConnection對象的onServiceConnected方法的第二個參數。4.AIDL介面工作原理    當在工程中實現了一個.aidl的AIDL介面源檔案(如/src/com/android_aidlservice/ICat.aidl),我們可以通過兩種方式產生需要的ICat.java介面檔案:一是使用Android SDK安裝目錄下的platform-tools子錄下的aidl.exe工具;二是ADT工具自動為該AIDL介面產生實現(路徑:gen/com.example.android_aidlservice/ICat.java)。ICat.java介面包含一個Stub內部類,該內部類實現了IBinder、ICat兩個介面,這個Stub類將會作為遠程Service的回調類---它實現了IBinder介面,因此可作為Service的onBind()方法的返回值。    二、處理序間通訊開發思路1.服務端-遠程Service開發(1)定義一個AIDL介面,檔案名稱為xxx.aidl,儲存到源碼所在的路徑,如/src/com/android_aidlservice/ICat.aidl;package com.example.android_aidlservice;interface ICat{     String getColor();     double getWeight();}其中,com.example.android_aidlservice為其所在的包名。(2)定義一個Service實作類別,並實現一個內部類繼承於Stub即實現了ICat介面,也就實現了IBinder介面。該Service的onBind()方法所返回的IBinder對象為ICat.Stub的子類的執行個體。private CatBinder catBinder;public class CatBinder extends Stub{    ......}@Overridepublic IBinder onBind(Intent arg0){    return catBinder;}(3)在AndroidMainfest.xml工程檔案中配置該Service    <application .... >        <!--定義一個Service組件-->        <service android:name=".AidlService">            <intent-filter>                <action android:name="com.example.sercie.AIDL_SERVICE"></action>            </intent-filter>        </service>  </application>2.用戶端開發思路(1)定義一個AIDL介面,檔案名稱為xxx.aidl,儲存到源碼所在的路徑,如/src/com/android_aidlservice/ICat.aidl;package com.example.android_aidlservice;interface ICat{     String getColor();     double getWeight();}其中,com.example.android_aidlservice為其所在的包名,該.aidl檔案為從Service段的AIDL介面檔案複製到用戶端應用中。(2)建立ServiceConnection對象,並在ServiceConnection對象的onServiceConnected方法中添加如下代碼:    catService = ICat.Stub.asInterface(service);其中,catService為Service的onBind()方法返回IBinder對象的代理。(3)以ServiceConnection對象作為參數,調用Context的bindService()方法綁定並啟動遠程Service即可。三、源碼實現1.服務端(1)定義一個Service實作類別-/src/com/example/android_service/AidlService.java

package com.example.android_aidlservice;import java.util.Timer;import java.util.TimerTask;import com.example.android_aidlservice.ICat.Stub;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;public class AidlService extends Service { //1.聲明一個IBinder對象、Timer對象 private CatBinder catBinder; private Timer timer; //2.定義兩個數組與兩個私人變數 private String color; private double weight; String[] colors = new String[]{"黑色","黃色","紅色"}; double[] weigths=new double[]{2.3,3.1,1.58}; //3.繼承stub,也就實現了ICat介面,並實現了IBinder介面 public class CatBinder extends Stub {  @Override  public String getColor() throws RemoteException {   return color;  }  @Override  public double getWeight() throws RemoteException {   return weight;  }  } //4.當Service建立時調用該方法 @Override public void onCreate() {  super.onCreate();  //a.執行個體化一個CatBinder對象  catBinder = new CatBinder();  //b.該service完成的任務:隨機地改變Service組件內color、weight屬性的值  timer.schedule(new TimerTask(){   @Override   public void run() {    int rand=(int)(Math.random()*3);    color=colors[rand];    weight = weigths[rand];    System.out.println("-----------"+rand);   }  }, 0, 800); } /*5.訪問者使用bindService()方法啟動Service時,該方法用於返回catBinder對象  * (1)在綁定本地Service的情況下,該catBinder對象會直接傳給用戶端的ServiceConnection對象;  * (2)在綁定遠程Service的情況下,只將catBinder對象的代理傳遞給用戶端的ServiceConnection對象的  * onServiceConnection方法的第二個參數*/ @Override public IBinder onBind(Intent intent) {  return catBinder; } //6.回調該方法關閉Service @Override public void onDestroy() {  timer.cancel(); }}
(2)在AndroidManifest檔案中配置該Service
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.android_aidlservice"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="19" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <service android:name=".AidlService"              android:exported="true">            <intent-filter>                <action android:name="com.example.service.AIDL_SERVICE"/>            </intent-filter>        </service>    </application></manifest>
2.用戶端(1)定義一個Activity實作類別-/src/com/example/android_service/AidlClient.java
package com.example.android_aidl_service;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.EditText;public class AidlClient extends Activity { private ICat catService;//聲明一個ICat對象 private Button get; private EditText color,weight;  //1.建立一個ServiceConnection對象 private ServiceConnection conn=new ServiceConnection(){  @Override  public void onServiceConnected(ComponentName name, IBinder service) {   //擷取遠程Service的onBind方法的對象的代理   catService = ICat.Stub.asInterface(service);  }  @Override  public void onServiceDisconnected(ComponentName name) {   catService=null;  } };  //2.綁定遠程Service並擷取其內容 @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  //a.擷取Activity主介面組件  setContentView(R.layout.main);  get=(Button)findViewById(R.id.get);  color=(EditText)findViewById(R.id.color);  weight=(EditText)findViewById(R.id.weight);   //b.建立所需綁定的Service的Intent並設定其Action屬性(即指定啟動哪個遠程Service)  Intent intent=new Intent();  intent.setAction("com.example.service.AIDL_SERVICE");  //c.綁定並啟動遠程Service  bindService(intent,conn,Service.BIND_AUTO_CREATE);  //d.通過IBinder對象的代理擷取遠程Service資料  get.setOnClickListener(new OnClickListener(){   @Override   public void onClick(View v)   {    try    {     color.setText(catService.getColor());     weight.setText(catService.getWeight()+"");    }    catch (RemoteException e) {     e.printStackTrace();    }   }  }); } //3.退出Activity時調用該方法,解除遠程Service的綁定 @Override protected void onDestroy() {  super.onDestroy();  this.unbindService(conn); }}
(2)在AndroidManifest檔案中配置該Activity
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.android_aidl_service"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="19" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".AidlClient"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>
效果:運行用戶端程式,單擊程式介面中"擷取遠程Service的資料"按鈕,就會實現用戶端讀取遠程Service功能。

相關文章

聯繫我們

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