Android多進(jìn)程間采用AIDL方式進(jìn)行通信
在上一節(jié)中,我介紹了Android中Service的生命周期以及一些有關(guān)知識。在這一節(jié)中,我采用代碼編寫的方式來介紹一下不同程序之間也就是不同進(jìn)程之間通信采用AIDL方式。
首先我需要解釋一下,不同程序進(jìn)程間采用AIDL方式啟動服務(wù),我們可以看作成client客戶端與server服務(wù)端之間的通信,無非c/s都是安裝在了我們的智能手機(jī)設(shè)備Android系統(tǒng)之上。好了,理解到這里我們就可以繼續(xù)往下介紹了。
首先我們編寫server服務(wù)端程序:
1)我們新建一個(gè)應(yīng)用程序S,它的應(yīng)用程序架構(gòu)如下:
2)我們在com.lgy.s包下編寫S.aidl文件,具體代碼如下:(aidl編碼格式不再敘述)
package com.lgy.s; interface S{ String getStr(String name); }
編寫好S.aidl文件我們就可以使用S.stub類下的相關(guān)方法。
3)我們可以自定義我們的Service了,具體代碼如下:
package com.lgy.s; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class MyService extends Service { private static final String TAG = "MyService"; private S.Stub server; @Override public void onCreate() { Log.i(TAG, "onCreate"); server = new S.Stub() { @Override public String getStr(String name) throws RemoteException { Log.i(TAG, name); return name; } }; super.onCreate(); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); server = null; super.onDestroy(); } @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind"); return server; } }
4)我們進(jìn)行服務(wù)端Server最后一步,在AndroidManifest.xml文件中注冊服務(wù)Service
<service android:name="com.lgy.s.MyService"> <intent-filter > <action android:name="android.lgy.myService" /> </intent-filter> </service>
-----------到此我們服務(wù)器端就編寫完畢------------------------
下面我們編寫客戶端client應(yīng)用程序:
1)我們新建一個(gè)應(yīng)用程序C,具體應(yīng)用架構(gòu)如下:
2)我們將在服務(wù)器端S寫的aidl原封不動的移到客戶端C上來(注包文件名都原封不動),移動后架構(gòu)如下圖:
3)我們就可以在客戶端MainActivity中直接調(diào)用綁定服務(wù)器上的服務(wù),具體代碼如下:
package com.lgy.c; import android.app.Activity; 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.util.Log; import android.view.View; import com.lgy.s.S; public class MainActivity extends Activity { protected static final String TAG = "MainActivity"; private S s; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { s = S.Stub.asInterface(service); Log.i(TAG, "onServiceConnected client"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void bindBtn(View v){ Intent mIntent = new Intent("android.lgy.myService"); bindService(mIntent, conn, BIND_AUTO_CREATE); } public void greetBtn(View v){ try { Log.i(TAG, s.getStr("client")); } catch (RemoteException e) { e.printStackTrace(); } } public void unbindBtn(View v){ unbindService(conn); } }
4)MainActivity對應(yīng)的布局文件代碼如下:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.lgy.c.MainActivity" > <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:onClick="bindBtn" android:text="綁定服務(wù)器Service" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:onClick="greetBtn" android:text="傳遞參數(shù)給服務(wù)器獲取返回的數(shù)據(jù)" /> <Button android:id="@+id/button3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button2" android:layout_below="@+id/button2" android:onClick="unbindBtn" android:text="解除綁定服務(wù)" /> </RelativeLayout>
至此為止客戶端代碼我們已經(jīng)編寫完畢。
下面我們開始測試:
我們不運(yùn)行服務(wù)器端,而是直接運(yùn)行客戶端的話,相對應(yīng)的效果會怎么樣呢?具體效果如下解析:
第一、我們點(diǎn)擊綁定服務(wù)的話,系統(tǒng)程序無任何反應(yīng),這個(gè)時(shí)候在客戶端服務(wù)已經(jīng)綁定,但是沒有連接到服務(wù)端。接著我們再次點(diǎn)解讀取數(shù)據(jù)的話,系統(tǒng)將會崩潰。因?yàn)闆]有連接到服務(wù)器端方法沒有具體實(shí)現(xiàn)。
第二、我們點(diǎn)擊綁定服務(wù)的話,系統(tǒng)程序無任何反應(yīng),這個(gè)時(shí)候在客戶端服務(wù)已經(jīng)綁定,但是沒有連接到服務(wù)端,接著我們點(diǎn)擊解除服務(wù)綁定的話,系統(tǒng)仍然沒有任何反應(yīng),我們要是再接著點(diǎn)擊解除服務(wù)綁定的話,系統(tǒng)就會崩潰,這也就從而再次證明了服務(wù)只會綁定一次,多次綁定的話服務(wù)不會做出任何反應(yīng);服務(wù)解除綁定只能僅只能解除綁定一次,多次解除綁定服務(wù)的話,系統(tǒng)就會崩潰。
第三、我們直接點(diǎn)擊接受數(shù)據(jù),系統(tǒng)程序也會崩潰,原因就是在于服務(wù)沒有綁定,服務(wù)端根本就沒有連接,相當(dāng)于數(shù)據(jù)讀取方法沒有實(shí)現(xiàn)。
第四:我們直接點(diǎn)擊解除綁定的話,系統(tǒng)程序也會崩潰,原因就是在于服務(wù)一次也沒有綁定。
我們現(xiàn)在運(yùn)行服務(wù)器,相對應(yīng)的效果又會怎么樣呢?具體效果如下解析:
第一、我們點(diǎn)擊綁定服務(wù),可以觀察到后臺logcat日志信息:
從日志我們可以看出在客戶端C綁定服務(wù)同時(shí)連接服務(wù)端,可以看到服務(wù)端Service的啟動onCreate和服務(wù)Service綁定onBind。
第二、我們點(diǎn)擊獲取數(shù)據(jù),可以觀察到后臺logcat日志信息:
從日志圖中我們可以看出客戶端將client字符串?dāng)?shù)據(jù)傳遞給服務(wù)器端,服務(wù)器端接受并返回一個(gè)字符串?dāng)?shù)據(jù)。
第三、我們點(diǎn)擊解除綁定服務(wù),具體logcat如下:
第四:如果我們不點(diǎn)擊綁定服務(wù),而是直接點(diǎn)獲取數(shù)據(jù),或者解除綁定的話,系統(tǒng)都將會崩潰,具體原因前面已經(jīng)解釋清楚,在此不作過多重復(fù)。
以上就是AIDL在多進(jìn)程中通信調(diào)用的簡單應(yīng)用(C應(yīng)用程序啟動S應(yīng)用程序服務(wù)Service)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android使用AIDL方式實(shí)現(xiàn)播放音樂案例
- Android AIDL實(shí)現(xiàn)兩個(gè)APP間的跨進(jìn)程通信實(shí)例
- Android使用AIDL實(shí)現(xiàn)兩個(gè)App間通信
- Android應(yīng)用程序四大組件之使用AIDL如何實(shí)現(xiàn)跨進(jìn)程調(diào)用Service
- 使用Android studio創(chuàng)建的AIDL編譯時(shí)找不到自定義類的解決辦法
- Android 使用【AIDL】調(diào)用外部服務(wù)的解決方法
- 基于Android AIDL進(jìn)程間通信接口使用介紹
- Android程序設(shè)計(jì)之AIDL實(shí)例詳解
- 實(shí)例講解Android中的AIDL內(nèi)部進(jìn)程通信接口使用
- Android Studio創(chuàng)建AIDL文件并實(shí)現(xiàn)進(jìn)程間通訊實(shí)例
相關(guān)文章
Android 中 ActivityLifecycleCallbacks的實(shí)例詳解
這篇文章主要介紹了Android 中 ActivityLifecycleCallbacks的實(shí)例詳解的相關(guān)資料,希望通過本文大家能掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09Android NDK 開發(fā)中 SO 包大小壓縮方法詳解
這篇文章主要為為大家介紹了Android NDK 開發(fā)中 SO 包大小壓縮方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Flutter質(zhì)感設(shè)計(jì)之底部導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了Flutter質(zhì)感設(shè)計(jì)之底部導(dǎo)航的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android 中 Fragment 嵌套 Fragment使用存在的bug附完美解決方案
本文從兩個(gè)方面淺析Android 中 Fragment 嵌套 Fragment使用存在的bug問題,原因找到就可以完美的解決了,對fragment嵌套fragment使用相關(guān)知識感興趣的朋友一起看看吧2016-08-08基于flutter?sound插件實(shí)現(xiàn)錄音與播放功能
這篇文章主要介紹了基于flutter?sound插件實(shí)現(xiàn)錄音與播放功能,介紹了如何錄音,如何播放本地和遠(yuǎn)程音頻文件,以及如何實(shí)現(xiàn)動畫,在錄制完音頻文件后如何上傳,這些都是我們平常使用這個(gè)功能會遇到的問題。在使用的過程中遇到的問題也有列出,需要的朋友可以參考下2022-05-05Android中的動態(tài)加載機(jī)制的學(xué)習(xí)研究
本篇文章主要介紹了Android中的動態(tài)加載機(jī)制,對android項(xiàng)目開發(fā)有著一定的幫助,有興趣的同學(xué)可以了解一下。2016-11-11