您好,登錄后才能下訂單哦!
AIDL文件怎么在Android Studio項目中創建?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
在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); } }
關于AIDL文件怎么在Android Studio項目中創建問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。