Android使用AIDL實(shí)現(xiàn)兩個(gè)App間通信
今天開(kāi)發(fā)了一個(gè)功能,通過(guò)Android的AIDL機(jī)制完成兩個(gè)app間的通信。功能需求很簡(jiǎn)單,一個(gè)客戶端app,叫做client,一個(gè)服務(wù)端app叫orderManager;客戶端負(fù)責(zé)展示訂單列表,并且可以向服務(wù)端添加訂單;服務(wù)端負(fù)責(zé)管理訂單,可以對(duì)外提供訂單信息。
閑言少敘,下面直接上代碼。
1、編寫(xiě)bean類(lèi)。
首先在client中定義OrderBean類(lèi),字段很簡(jiǎn)單,注意需要實(shí)現(xiàn)Parcelable接口:
package com.example.wang.client.bean; import android.os.Parcel; import android.os.Parcelable; public class OrderBean implements Parcelable{ private String id; private String name; private int amount; public OrderBean(){} public OrderBean(String id, String name, int amount) { this.id = id; this.name = name; this.amount = amount; } protected OrderBean(Parcel in) { id = in.readString(); name = in.readString(); amount = in.readInt(); } public static final Creator<OrderBean> CREATOR = new Creator<OrderBean>() { @Override public OrderBean createFromParcel(Parcel in) { return new OrderBean(in); } @Override public OrderBean[] newArray(int size) { return new OrderBean[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(id); dest.writeString(name); dest.writeInt(amount); } //get/set方法略 }
2、定義aidl文件。aidl文件的存放位置在Android Studio中一般存放在如下路徑:
client/src/aidl/…
// OrderBean.aidl package com.example.wang.client.bean;//存放的包路徑同bean類(lèi) parcelable OrderBean;//通信用到的Parcelable需要聲明,并且使用小寫(xiě)的parcelable // IBookManager.aidl package com.example.wang.client.aidl; import com.example.wang.client.bean.OrderBean;//除了系統(tǒng)提供的對(duì)象,都需要明確導(dǎo)入 interface IOrderManager { List<OrderBean> getAll(); void add(in OrderBean bean); }
3、定義布局文件,編寫(xiě)MainActivity。這個(gè)很簡(jiǎn)單,Button和RecyclerView結(jié)合即可:
#activity_main.xml - 主頁(yè)面布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="5dp" android:text="訂單管理" android:textSize="20dp"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp"> <Button android:id="@+id/search_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15dp" android:text="刷新訂單"/> <Button android:id="@+id/add_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15dp" android:text="添加訂單"/> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
還要寫(xiě)一個(gè)item_order.xml,用于RecyclerView的展示,很簡(jiǎn)單,此處略過(guò)。
//MainActivity.java package com.example.wang.client; ... public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private List<OrderBean> orderList; private IOrderManager orderManager; //UI private Button search_button; private Button add_button; private RecyclerView recyclerView; private OrderAdapter adapter; ServiceConnection conn = new ServiceConnection() {//這個(gè)最重要,用于連接Service @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("MainActivity.conn","@@ onServiceConnected name="+name); IOrderManager manager = IOrderManager.Stub.asInterface(service); orderManager = manager; refreshOrderList(); try { service.linkToDeath(deathRecipient, 0); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { Log.i("MainActivity.conn","@@ onServiceDisconnected name="+name); } }; IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {//注冊(cè)一個(gè)死亡代理,監(jiān)測(cè)連接狀態(tài) @Override public void binderDied() { Log.i("MainActivity","@@ binderDied "+(orderManager==null)); if(orderManager==null){ return; } orderManager.asBinder().unlinkToDeath(deathRecipient, 0); orderManager = null; //重新綁定 bindOrderService(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i("MainActivity","@@ onCreate"); setContentView(R.layout.activity_main); getLayoutInflater(); //view search_button=findViewById(R.id.search_button); add_button=findViewById(R.id.add_button); recyclerView=findViewById(R.id.recyclerView); //組裝recyclerView LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(linearLayoutManager); adapter=new OrderAdapter(this); recyclerView.setAdapter(adapter); //onclick search_button.setOnClickListener(this); add_button.setOnClickListener(this); //bind bindOrderService(); } private void bindOrderService(){ Intent intent = new Intent("com.example.wang.ordermanager.OrderService"); intent.setPackage("com.example.wang.ordermanager"); intent.addCategory(Intent.CATEGORY_LAUNCHER); bindService(intent, conn, Context.BIND_AUTO_CREATE); } /** * 重新獲取數(shù)據(jù)并刷新列表。 */ private void refreshOrderList(){ try { if(orderManager!=null){ orderList = orderManager.getAll(); } if(orderList!=null){ adapter.setData(orderList); adapter.notifyDataSetChanged(); } } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onClick(View v) { if(v==search_button){ //刷新訂單 refreshOrderList(); }else if(v==add_button){ //增加訂單 try { OrderBean orderBean=new OrderBean(); Random random=new Random(); orderBean.setAmount(random.nextInt(800)+100); orderBean.setId(random.nextInt(100000000)+100000+""); orderBean.setName("玩具"+random.nextInt()); orderManager.add(orderBean); refreshOrderList(); } catch (RemoteException e) { e.printStackTrace(); } } } @Override protected void onDestroy() { super.onDestroy(); unbindService(conn); } }
4、編寫(xiě)服務(wù)端代碼
這里主要做兩件事,第一個(gè)是移植aidl文件和bean類(lèi),將client中的aidl文件和OrderBean移植過(guò)來(lái),文件路徑要保持一致,第二個(gè)是編寫(xiě)OrderService.java類(lèi)。
//OrderService.java package com.example.wang.ordermanager; ... public class OrderService extends Service{ private CopyOnWriteArrayList<OrderBean> list = new CopyOnWriteArrayList<>(); @Override public void onCreate() { super.onCreate(); Log.i("OrderService","@@ onCreate"); } @Nullable @Override public IBinder onBind(Intent intent) { Log.i("OrderService","@@ onBind"); return binder; } Binder binder = new IOrderManager.Stub(){ @Override public List<OrderBean> getAll() throws RemoteException { return list; } @Override public void add(OrderBean bean) throws RemoteException { list.add(bean); } }; }
OrderService服務(wù)在AndroidManifest.xml中的配置如下:
<service android:name=".OrderService" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="com.example.wang.ordermanager.OrderService"/> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </service>
代碼編寫(xiě)就完成了,運(yùn)行時(shí)需要先運(yùn)行服務(wù)端app,再運(yùn)行client,如果運(yùn)行過(guò)程中OrderService服務(wù)斷掉了,client會(huì)通過(guò)死亡代理得到通知,再重新綁定即可。
運(yùn)行如下:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Textview實(shí)現(xiàn)顏色漸變滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Android Textview實(shí)現(xiàn)顏色漸變滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10android支付寶客戶端html5網(wǎng)頁(yè)無(wú)法自動(dòng)關(guān)閉問(wèn)題的解決方法
這篇文章主要為大家詳細(xì)介紹了android支付寶客戶端html5網(wǎng)頁(yè)無(wú)法自動(dòng)關(guān)閉問(wèn)題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Android網(wǎng)絡(luò)開(kāi)發(fā)中GET與POST請(qǐng)求詳解
這篇文章主要介紹了android實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求的get和post請(qǐng)求的簡(jiǎn)單封裝與使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧<BR>2022-12-12Android實(shí)現(xiàn)儀表盤(pán)效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)儀表盤(pán)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05Android控件AppWidgetProvider使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android控件AppWidgetProvider的使用方法詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android自定義水波紋底部導(dǎo)航的實(shí)現(xiàn)
TabLayout作為導(dǎo)航組件來(lái)說(shuō),使用場(chǎng)景非常的多,也意味著要滿足各種各樣的需求,這篇文章主要介紹了Android自定義水波紋底部導(dǎo)航的實(shí)現(xiàn)2022-08-08Android自定義流式布局的實(shí)現(xiàn)示例
這篇文章主要介紹了Android自定義流式布局的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Android中使用am命令實(shí)現(xiàn)在命令行啟動(dòng)程序詳解
這篇文章主要介紹了Android中使用am命令實(shí)現(xiàn)在命令行啟動(dòng)程序詳解,本文詳細(xì)講解了am命令的語(yǔ)法,然后給出了啟動(dòng)內(nèi)置程序的操作實(shí)例,需要的朋友可以參考下2015-04-04詳解Android權(quán)限管理之Android 6.0運(yùn)行時(shí)權(quán)限及解決辦法
本篇文章主要介紹Android權(quán)限管理之Android 6.0運(yùn)行時(shí)權(quán)限及解決辦法,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-11-11