国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android Studio創建AIDL文件并實現進程間通訊實例

2019-12-12 03:09:23
字體:
來源:轉載
供稿:網友

在Android系統中,跨進程通信是非常普遍的事情,它用到了Binder機制處理進程之間的交互。Binder機制會開放一些接口給Java層,供android開發工程師調用進程之間通信。這些接口android封裝到了AIDL文件里,當我們項目用到跨進程通信時可以創建.aidl文件,.aidl文件可以協助我們達到跨進程的通信。下面簡單介紹用AndroidStudio創建AIDL文件的過程。

a.新建AIDL文件

1.項目文件夾右鍵---> new --->選擇AIDL

2.自定義一個接口名稱

3.創建之后我們看到了xxx.aidl文件,然后編輯自己項目需要實現的方法,這里很簡單就獲取一個字符串的方法getAllName。

4.寫好之后,我們需要重新ReBuild,完后在項目build/generated/source/aidl/debug/包名 目錄下就看到了系統為我們生成的以剛才.aidl文件名命名的java文件。

該java文件系統會自動生成代碼:

Stub:描述了一個Java服務,對應是一個遠程的Service。

Proxy:描述了一個Java服務的代理對象,在Client端就會得到這個對象。

這兩者都實現了IPersonManager接口。

asInterface:將Java服務的代理對象即一個BinderProxy封裝成了一個IPersonManager.Stub.Proxy對象,實現了IPersonManager接口。

onTransact:負責接收分發進程間的通信。它首先會收到Client發來的請求,不同的方法進入相應的case代碼中,然后交給Stub的子類去處理事件,例如 java.lang.String _result = this.getAllName();   這里的this就可以讓它的子類去接收該請求并處理。
IBinder的transact方法:用來發送進程間的請求。

b.利用AIDL實現進程間的通訊

一:接口文件中只含有基礎數據類型

如上aidl文件,IPersonManager中只用到了基本數據類型,此時要完善Server端的小項目,還需要新建一個Service。
Server端代碼如下

public class PersonService extends Service {    private static String names = "alice & iland";   public PersonBinder mPersonBinder;   @Override   public void onCreate() {     super.onCreate();     mPersonBinder = new PersonBinder();   }    @Override   public IBinder onBind(Intent intent) {     return mPersonBinder;   }   public class PersonBinder extends IPersonManager.Stub{      @Override     public String getAllName() throws RemoteException {       return names;     }   }  } 

繼承系統的Service,并建立一個內部類繼承IPersonManager.Stub,這里很簡單,當客戶端請求要獲取名字時我們這里把names給到客戶端。

Client端代碼如下

public class MainActivity extends AppCompatActivity implements View.OnClickListener{   private static final String TAG = "MainActivity";   private Button btnGet;   private EditText etShow;   public IPersonManager mIPersonManager;   ServiceConnection sc = new ServiceConnection() {     @Override     public void onServiceConnected(ComponentName name, IBinder service) {       Log.i(TAG, "onServiceConnected: ");       mIPersonManager = IPersonManager.Stub.asInterface(service);     }      @Override     public void onServiceDisconnected(ComponentName name) {       Log.i(TAG, "onServiceDisconnected: ");       mIPersonManager = null;     }   };   @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     btnGet = (Button) findViewById(R.id.btn_getname);     etShow = (EditText) findViewById(R.id.et_allnamef);     btnGet.setOnClickListener(this);      Intent intent = new Intent("com.ly.testaidlserver.aidl.AIDL_SERVICE");     intent.setPackage("com.ly.testaidlserver");     bindService(intent,sc, Service.BIND_AUTO_CREATE);   }    @Override   public void onClick(View v) {     switch (v.getId()){       case R.id.btn_getname:         String names = null;         try {           if (mIPersonManager!=null)             names = mIPersonManager.getAllName();         } catch (RemoteException e) {           e.printStackTrace();         }         etShow.setText(names);         break;       default:         break;     }   }@Override   protected void onDestroy() {     super.onDestroy();     unbindService(sc);   }  } 

在onServiceConnected方法中拿到IPersonManager的代理對象,最終獲取到 alice & ilan,與服務端數據一致。

注意:

1.bindService方法在5.0以后做出改變,隱式意圖需要設置Package 或者 Commponent,直接定義一個action是報異常的。

Intent intent = new Intent("com.ly.testaidlserver.aidl.AIDL_SERVICE"); intent.setPackage("com.ly.testaidlserver");bindService(intent,sc, Service.BIND_AUTO_CREATE); 

2.我們需要把Server端的aidl文件復制到Client端,在Client中存放aidl的文件夾也需要跟Server端包名一致。

如圖:

上圖為aidl文件在Server端存放的路徑,下圖為復制到Client端aidl文件的路徑,這里要保持一致,因此Client端需要針對Server端的包名新建一個Package。

3.當我們啟動項目的時候,如果在Activity中IPersonManager找不到報出異常,請在app的build.gradle中添加aidl文件指名目錄,如本例中添加,

  sourceSets{    main {      aidl.srcDirs = ['src/main/aidl','src/main/java']    }  }

二:接口文件中含有復雜數據類型、

1.新建一個Person.aidl     內容非常簡單
parcelable Person;

2.新建一個Person實體類,為了能在進程間進行通信必須實現Parcelable接口。

3.在IPersonManager中添加了一個方法,這里注意用到的Person類必須將包名improt進去。

4.將IPersonManager.aidl、Person.aidl、Person.java復制到客戶端的aidl包下。

5.查看是否需要修改build.gradle中sourceSets設置

代碼基本沒有變化:

Person.java

public class Person implements Parcelable {   String name;   int age;    public Person(String name, int age) {     this.name = name;     this.age = age;   }    public static final Creator<Person> CREATOR = new Creator<Person>() {     @Override     public Person createFromParcel(Parcel in) {       return new Person(in.readString(), in.readInt());     }      @Override     public Person[] newArray(int size) {       return new Person[size];     }   };    @Override   public int describeContents() {     return 0;   }    @Override   public void writeToParcel(Parcel dest, int flags) {     dest.writeString(name);     dest.writeInt(age);   }    public String getName() {     return name;   }    public void setName(String name) {     this.name = name;   }    public int getAge() {     return age;   }    public void setAge(int age) {     this.age = age;   } } 

IPersonManager.aidl

interface IPersonManager {   String getAllName();   List<Person> getPersonList(); } 

Server

public class PersonService extends Service {    private List<Person> persons = new ArrayList<Person>();   public PersonBinder mPersonBinder;   @Override   public void onCreate() {     super.onCreate();     mPersonBinder = new PersonBinder();     Person p1 = new Person("alice",23);     persons.add(p1);     Person p2 = new Person("iland",18);     persons.add(p2);   }    @Override   public IBinder onBind(Intent intent) {     return mPersonBinder;   }   public class PersonBinder extends IPersonManager.Stub{      @Override     public String getAllName() throws RemoteException {       return "";     }      @Override     public List<Person> getPersonList() throws RemoteException {       return persons;     }   } } 

Clent

public class MainActivity extends AppCompatActivity implements View.OnClickListener{   private static final String TAG = "MainActivity";   private Button btnGet;   private EditText etShow;   public IPersonManager mIPersonManager;   ServiceConnection sc = new ServiceConnection() {     @Override     public void onServiceConnected(ComponentName name, IBinder service) {       Log.i(TAG, "onServiceConnected: ");       mIPersonManager = IPersonManager.Stub.asInterface(service);     }      @Override     public void onServiceDisconnected(ComponentName name) {       Log.i(TAG, "onServiceDisconnected: ");       mIPersonManager = null;     }   };   @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     btnGet = (Button) findViewById(R.id.btn_getname);     etShow = (EditText) findViewById(R.id.et_allnamef);     btnGet.setOnClickListener(this);      Intent intent = new Intent("com.ly.testaidlserver.aidl.AIDL_SERVICE");     intent.setPackage("com.ly.testaidlserver");     bindService(intent,sc, Service.BIND_AUTO_CREATE);   }    @Override   public void onClick(View v) {     switch (v.getId()){       case R.id.btn_getname:         ArrayList<Person> persons = null;         try {           if (mIPersonManager!=null)             persons = (ArrayList<Person>) mIPersonManager.getPersonList();         } catch (RemoteException e) {           e.printStackTrace();         }         String result = "";         for (Person person : persons){           result = result+person.getName()+"__"+person.getAge();         }         etShow.setText(result);         break;       default:         break;     }   }@Override   protected void onDestroy() {     super.onDestroy();     unbindService(sc);   }  } 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 承德县| 蒙山县| 商丘市| 吴忠市| 石台县| 中阳县| 启东市| 杭锦后旗| 江北区| 海宁市| 托里县| 饶阳县| 项城市| 隆子县| 重庆市| 灵川县| 林甸县| 南漳县| 马山县| 嘉禾县| 金昌市| 怀柔区| 上饶市| 湘阴县| 罗山县| 新宁县| 寿阳县| 青田县| 清镇市| 牡丹江市| 靖远县| 峨山| 敖汉旗| 青铜峡市| 新昌县| 定远县| 博野县| 巩留县| 四会市| 沙田区| 武川县|