日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > ChatGpt >内容正文

ChatGpt

android进程间通信:使用AIDL

發布時間:2023/12/4 ChatGpt 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android进程间通信:使用AIDL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

android 的binder其實是基于 openbinder實現的,openbinder的地址:http://www.angryredplanet.com/~hackbod/openbinder/docs/html/

http://blog.csdn.net/saintswordsman/article/details/5130947

?

歡迎閱讀本文,你能關注本文,你知道你需要進程間通信、需要AIDL(以及Binder),那么可以默認你對這些概念已經有了一些了解,你(大致) 知道它們是什么,它們有什么用,所以為了節約大家的眼力和時間,在此我不復制粘貼網上泛濫的博客或者翻譯冗長的android文檔。

????? 關于AIDL的介紹在文檔:docs/guide/developing/tools/aidl.html

????? 關于IBinder的介紹在文檔:docs/reference/android/os/IBinder.html

????? 以及Binder:docs/reference/android/os/Binder.html

????? 在后文中,我將以我自己的理解向你介紹相關的概念。以我目前粗淺的經驗,應用程序使用AIDL的地方,幾乎都和Service有關,所以你也需要知道一些關于Service的知識。日后得閑我也會繼續寫一些關于Service的貼。

????? 本文將以一個例子來和你分享使用AIDL的基礎技能,這個例子里有:

1、一個類mAIDLActivity,繼承Activity。里面有三個按鈕,text分別為StartService,StopService,CallbackTest。

2、一個類mAIDLService,繼承Service。為了充分展示ADIL的功能,它做以下工作:當用戶點擊CallbackTest按鈕時,從mAIDLActivity調用mAIDLService中的Stub 對象的一個方法invokCallBack(),而這個方法又會調用mAIDLActivity中Stub 對象的一個方法performAction(),這個方法在屏幕上顯示一個toast。沒什么意義,只是展示一下AIDL如何使用。

3、兩個AIDL文件:forService.aidl和forActivity.aidl。對應名字,在Service和Activity中分別有對象需要用到它們定義的接口。

4、相關XML文件,略過。關于manifest中Service的語法,見docs/guide/topics/manifest /service-element.html。你也可以簡單地在<application></application>中加入

???? <service android:name=".mAIDLService" android:process=":remote"> </service>

開發環境為Eclipse。

揀重要的先說,來看看aidl文件的內容:

文件:forActivity.aidl

package com.styleflying.AIDL; interface forActivity { void performAction(); }

文件:forService.aidl

package com.styleflying.AIDL; import com.styleflying.AIDL.forActivity; interface forService { void registerTestCall(forActivity cb); void invokCallBack(); }

這兩個文件和Java文件放置的地方一樣,看包名。

在Eclipse中它們將被自動編譯為forActivity.java和forService.java,它們存放在gen目錄下。為了方便手頭無法演練的讀者,代碼不貼,不用細看。

?

再看mAIDLActivity.java:

package com.styleflying.AIDL; import android.app.Activity; import android.content.ComponentName; import android.content.Context; 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 android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class mAIDLActivity extends Activity { private static final String TAG = "AIDLActivity"; private Button btnOk; private Button btnCancel; private Button btnCallBack; private void Log(String str) { Log.d(TAG, "------ " + str + "------"); } private forActivity mCallback = new forActivity.Stub() { public void performAction() throws RemoteException { Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show(); } }; forService mService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = forService.Stub.asInterface(service); try { mService.registerTestCall(mCallback);} catch (RemoteException e) { } } public void onServiceDisconnected(ComponentName className) { Log("disconnect service"); mService = null; } }; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); btnOk = (Button)findViewById(R.id.btn_ok); btnCancel = (Button)findViewById(R.id.btn_cancel); btnCallBack = (Button)findViewById(R.id.btn_callback); btnOk.setOnClickListener(new OnClickListener() { public void onClick(View v) { Bundle args = new Bundle(); Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class); intent.putExtras(args); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); startService(intent); } }); btnCancel.setOnClickListener(new OnClickListener() { public void onClick(View v) { unbindService(mConnection); //stopService(intent); } }); btnCallBack.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { mService.invokCallBack(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } }

很短,相信大家很容易看明白。注意mConnection,它的onServiceConnected()中有一句mService = forService.Stub.asInterface(service);給mService賦值了,這個mService是一個 forService,而service是onServiceConnected()傳進來的參數,onServiceConnected()會在連接 Service的時候被系統調用,這個service參數的值來自哪里呢?

看mAIDLService.java:

package com.styleflying.AIDL; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.Log; public class mAIDLService extends Service { private static final String TAG = "AIDLService"; private forActivity callback; private void Log(String str) { Log.d(TAG, "------ " + str + "------"); } @Override public void onCreate() { Log("service create"); } @Override public void onStart(Intent intent, int startId) { Log("service start id=" + startId); } @Override public IBinder onBind(Intent t) { Log("service on bind"); return mBinder; } @Override public void onDestroy() { Log("service on destroy"); super.onDestroy(); } @Override public boolean onUnbind(Intent intent) { Log("service on unbind"); return super.onUnbind(intent); } public void onRebind(Intent intent) { Log("service on rebind"); super.onRebind(intent); } private final forService.Stub mBinder = new forService.Stub() { @Override public void invokCallBack() throws RemoteException { callback.performAction(); } @Override public void registerTestCall(forActivity cb) throws RemoteException { callback = cb; } }; }

注意onBind(),它的返回類型為IBinder,返回了一個mBinder,看看mBinder的定義:

??? private final forService.Stub mBinder = new forService.Stub() {

??????? @Override
??? ??? public void invokCallBack() throws RemoteException
??? ??? {
??? ??? ??? callback.performAction();
??? ???? }

??????? @Override
??? ??? public void registerTestCall(forActivity cb) throws RemoteException
??? ??? {
??? ??? ??? callback = cb;

??????? }

?????? };

它是實現了我們在AIDL中定義的方法,這個mBinder最終返回給了mAIDLActivity中的mService,于是在 mAIDLActivity中可以使用mBinder中的方法了。在mAIDLActivity中也有一個類似mBinder的對象,看看定義: ??

??????? private forActivity mCallback = new forActivity.Stub()

??? {
?? ??? ?public void performAction() throws RemoteException
?? ??? ?{
?? ??? ??? ?Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
?? ??? ?}
?? ?? };

我們要在界面上顯示一個toast,就是在這里實現的。這個對象,在mConnection的onServiceConnected()被調用時, 通過調用mService(也就是遠程的mAIDLService中的mBinder)的registerTestCall(),傳遞給了 mAIDLService,于是在mAIDLService中可以調用performAction()了。

很啰嗦,只為了能把這個細節說清楚。請大家認真看,我盡量避免錯別字、混亂的大小寫和邏輯不清的語法,相信你會看明白。是不是很簡單?再啰嗦一下,做一個大致總結,我們使用AIDL是要做什么呢:

讓Acticity(或者說一個進程/一個類?)和Service(或者說遠端進程/遠端類/對象?)獲取對方的一個Stub對象,這個對象在定義 時實現了我們在AIDL中定義的方法,于是這些遠程對象中的方法可以在本地使用了。如果這種使用(通信)是單向的,比如只是Activity需要通知 Service做什么,那么只要Service中有一個Stub對象,并且傳給Acticity就夠了。

至于如何獲得遠程的Stub,參看上面的代碼,看mConnection、registerTestCall、onRebind,它們展示了一種方法。

另外,有時候我們可能在一個類中有多個Stub對象,它們都要給遠程交互的類的實例,這個時候可以考慮使用RemoteCallbackList<>(docs/reference/android/os/RemoteCallbackList.html)。

?

=============================

Service的生命周期?Service的生命周期方法比Activity少一些,只有onCreate, onStart, onDestroy?
我們有兩種方式啟動一個Service,他們對Service生命周期的影響是不一樣的。

1 通過startService?
? ? Service會經歷 onCreate -> onStart?
? ?stopService的時候直接onDestroy?

? ?如果是調用者(TestServiceHolder)自己直接退出而沒有調用stopService的?
? ?話,Service會一直在后臺運行。?
? ?下次TestServiceHolder再起來可以stopService。

??2 通過bindService? ??
? ? Service只會運行onCreate, 這個時候 TestServiceHolder 和TestService綁定在一起?

? ?TestServiceHolder 退出了,Srevice就會調用onUnbind->onDestroyed?
? ?所謂綁定在一起就共存亡了。?

那有同學問了,要是這幾個方法交織在一起的話,會出現什么情況呢??
一 個原則是Service的onCreate的方法只會被調用一次,就是你無論多少次的startService又 bindService,Service只被創建一次。如果先是bind了,那么start的時候就直接運行Service的onStart方法,如果先 是start,那么bind的時候就直接運行onBind方法。如果你先bind上了,就stop不掉了,對啊,就是stopService不好使了,只 能先UnbindService, 再StopService,所以是先start還是先bind行為是有區別的。?


服 務不能自己運行,需要通過調用Context.startService()或Context.bindService()方法啟動服務。這兩個方法都可 以啟動Service,但是它們的使用場合有所不同。使用startService()方法啟用服務,調用者與服務之間沒有關連,即使調用者退出了,服務 仍然運行。使用bindService()方法啟用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特 點。

如 果打算采用Context.startService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用 onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法并不會導致多次創建服 務,但會導致多次調用onStart()方法。采用startService()方法啟動的服務,只能調用Context.stopService()方 法結束服務,服務結束時會調用onDestroy()方法。

如 果打算采用Context.bindService()方法啟動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,接著調用 onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接著調用onDestroy() 方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法并不會導致多次創建服務及綁定(也就是說 onCreate()和onBind()方法并不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方 法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法.

?

你可以綁定一個已經通過startService()方法啟動的服務。例如:一 個后臺播放音樂服務可以通過startService(intend)對象來播放音樂。可能用戶在播放過程中要執行一些操作比如獲取歌曲的一些信息,此時 activity可以通過調用bindServices()方法與Service建立連接。這種情況下,unbindService() 及 stopServices()方法實際上不會停止服務,直到最后一次的綁定被關閉。

?

================================================================

?

Android之進程間傳遞自定義類型參數

【0】AIDL默認支持的類型包話java基本類型(int、long、boolean等)和(String、List、Map、CharSequence)(好像數組也可以,只要實現了Parcelable接口),如果要傳遞自定義的類型該如何實現呢?

要傳遞自定義類型,首先要讓自定義類型支持parcelable協議,實現步驟如下:

1>自定義類型必須實現Parcelable接口,并且實現Parcelable接口的public void writeToParcel(Parcel dest, int flags)方法 。

2>自定義類型中必須含有一個名稱為CREATOR的靜態成員,該成員對象要求實現Parcelable.Creator接口及其方法。

3>創建一個aidl文件聲明你的自定義類型。

Parcelable接口的作用:實現了Parcelable接口的實例可以將自身的狀態信息(狀態信息通常指的是各成員變量的值)寫入Parcel,也可以從Parcel中恢復其狀態。 Parcel用來完成數據的序列化傳遞。?

【1】進程間傳遞自定義類型的實現過程?

1> 創建自定義類型,并實現Parcelable接口,使其支持parcelable協議。如:在com.hoo.domin創建Person.java:

  • public?class?Person?implements?Parcelable??
  • ??private?Integer?id;??
  • ??private?String?name;??
  • ???
  • ??public?Person(){}??
  • ??public?Person(Integer?id,?String?name)?{??
  • ??this.id?=?id;??
  • ??this.name?=?name;??
  • ??}??
  • ??public?Integer?getId()?{??
  • ??return?id;??
  • ??}??
  • ??public?void?setId(Integer?id)?{??
  • ??this.id?=?id;??
  • ??}??
  • ??public?String?getName()?{??
  • ??return?name;??
  • ??}??
  • ??public?void?setName(String?name)?{??
  • ??this.name?=?name;??
  • ??}???
  • ??@Override??
  • ??public?int?describeContents()?{??
  • ??return?0;??
  • ??}??
  • ??@Override??
  • ??public?void?writeToParcel(Parcel?dest,?int?flags)?{//把javanbean中的數據寫到Parcel ??
  • ??dest.writeInt(this.id);??
  • ??dest.writeString(this.name);??
  • ??}??
  • ??//添加一個靜態成員,名為CREATOR,該對象實現了Parcelable.Creator接口 ??
  • ??public?static?final?Parcelable.Creator<Person>?CREATOR?=?new?Parcelable.Creator<Person>(){??
  • ??@Override??
  • ??public?Person?createFromParcel(Parcel?source)?{//從Parcel中讀取數據,返回person對象 ??
  • ??return?new?Person(source.readInt(),?source.readString());??
  • ??}??
  • ??@Override??
  • ??public?Person[]?newArray(int?size)?{??
  • ??return?new?Person[size];??
  • ??}??
  • ??};??
  • }??
  • 2> 在自定義類型所在包下創建一個aidl文件對自定義類型進行聲明,文件的名稱與自定義類型同名。

    package com.hoo.domin

    parcelable Person;?

    3> 在接口aidl文件中使用自定義類型,需要使用import顯式導入,本例在com.hoo.aidl包下創建IPersonService.aidl文件,內容如下:

  • package?com.hoo.aidl;??
  • import?cn.itcast.domain.Person;??
  • interface?IPersonService?{??
  • ??????void?save(in?Person?person);??
  • }???
  • 4> 在實現aidl文件生成的接口(本例是IPersonService),但并非直接實現接口,而是通過繼承接口的Stub來實現(Stub抽象類內部實現了aidl接口),并且實現接口方法的代碼。內容如下:

  • public?class?ServiceBinder?extends?IPersonService.Stub?{??
  • ???????@Override??
  • ???????public?void?save(Person?person)?throws?RemoteException?{??
  • ??Log.i("PersonService",?person.getId()+"="+?person.getName());??
  • ???????}???
  • }??
  • 5> 創建一個Service(服務),在服務的onBind(Intent intent)方法中返回實現了aidl接口的對象(本例是ServiceBinder)。內容如下:

  • public?class?PersonService?extends?Service?{??
  • ??private?ServiceBinder?serviceBinder?=?new?ServiceBinder();??
  • ??@Override??
  • ??public?IBinder?onBind(Intent?intent)?{??
  • ??return?serviceBinder;??
  • ??}??
  • public?class?ServiceBinder?extends?IPersonService.Stub?{??
  • ???????@Override??
  • ???????public?void?save(Person?person)?throws?RemoteException?{??
  • ??Log.i("PersonService",?person.getId()+"="+?person.getName());??
  • ???????}??
  • }??
  • }??
  • 其他應用可以通過隱式意圖訪問服務,意圖的動作可以自定義,AndroidManifest.xml配置代碼如下:

  • <service?android:name=".PersonService"?>??
  • ??<intent-filter>??
  • ??<action?android:name="com.hoo.process.aidl.PersonService?"?/>??
  • ??</intent-filter>??
  • </service>?
  • ?

    總結

    以上是生活随笔為你收集整理的android进程间通信:使用AIDL的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲激情婷婷 | 久久精品国产99久久久 | 韩国三级免费 | 国产视频福利 | 国产精品免费一区 | 99精品自拍 | 国产成年人视频网站 | 一区二区三区www污污污网站 | 色婷婷亚洲| 实拍女处破www免费看 | 欧美小视频在线 | 久久久久久福利 | 巨胸喷奶水www久久久免费动漫 | 在线免费一区 | 奇米精品一区二区三区在线观看一 | 天天综合天天 | 人人超碰在线 | 玖草在线视频 | 香蕉视频免费在线看 | 国产精品污污 | 91国自产精品中文字幕亚洲 | 中文无码精品一区二区三区 | 欧美视频一区在线观看 | 中文字幕一区二区三区四区免费看 | 日本毛片在线看 | 成人午夜精品福利免费 | 精品一区二区三区av | 亚洲人在线 | 国产99久久精品 | 中文字幕一区二区在线播放 | 乐播av一区二区三区 | 国产强伦人妻毛片 | 一级视频片 | 国产人人草 | 搡国产老太xxx网站 高h喷汁呻吟3p | 国产精品乱码久久久久久 | 欧美偷拍一区二区 | 中国男人操女人 | 无码人妻精品一区二区中文 | 热久久网站| 日本黄色美女 | 亚洲一区二区三区免费视频 | 亚洲成人激情av | a级淫片 | 亚洲乱码国产乱码精品天美传媒 | 香蕉视频在线观看www | 日韩图片一区 | 毛片美女| 天天人人精品 | 精品国产av无码 | 国产区免费观看 | 国产精品影音先锋 | 天天射,天天干 | 国产精品久久久久久一区二区三区 | 免费人成又黄又爽又色 | 99亚洲天堂 | 日日人人 | 91精品国产视频 | 理想之城连续剧40集免费播放 | 98精品国产 | 久久成人人人人精品欧 | 三年中国片在线高清观看 | 黄色一级a毛片 | 影音先锋激情 | 91大片免费看 | 日本色网址 | 欧美精品一区二区三区蜜臀 | 18性xxxxx性猛交 | 精品色| 伊人久久av | 成人久草 | 色多多视频在线观看 | 国产欧美一区二区 | 欧美黑人精品 | 国产草草视频 | 在线播放中文字幕 | av我不卡| 性欧美大战久久久久久久 | 欧美xxxxx牲另类人与 | 午夜视频网站在线观看 | 四虎视频在线 | 久久99精品久久久久久水蜜桃 | 亚洲国产精品成人综合色在线婷婷 | 久久久午夜影院 | 绿帽人妻精品一区二区 | 天天拍夜夜拍 | 国产91绿帽单男绿奴 | 毛片久久久 | 亚洲成人中文 | 亚洲精品a | 97久久久久 | 成人免费毛片视频 | 少妇影院在线观看 | 国产亚洲欧美在线视频 | 国产精品久久777777毛茸茸 | 国产成人二区 | 黄网免费在线观看 | 噜噜噜久久 | 日本国产精品一区 |