Android進(jìn)程間通信的幾種方式 定義多進(jìn)程
創(chuàng)新互聯(lián)是一家專業(yè)提供鄂城企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、H5建站、小程序制作等業(yè)務(wù)。10年已為鄂城眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。
第一:Android應(yīng)用中使用多進(jìn)程只有一個(gè)辦法(用NDK的fork來(lái)做除外),就是在AndroidManifest.xml中聲明組件時(shí),用android:process屬性來(lái)指定。
不知定process屬性,則默認(rèn)運(yùn)行在主進(jìn)程中,主進(jìn)程名字為包名。
android:process = package:remote,將運(yùn)行在package:remote進(jìn)程中,屬于全局進(jìn)程,其他具有相同shareUID與簽名的APP可以跑在這個(gè)進(jìn)程中。
android:process = :remote ,將運(yùn)行在默認(rèn)包名:remote進(jìn)程中,而且是APP的私有進(jìn)程,不允許其他APP的組件來(lái)訪問(wèn)。
第二:多進(jìn)程引發(fā)的問(wèn)題
靜態(tài)成員和單例失效:每個(gè)進(jìn)程保持各自的靜態(tài)成員和單例,相互獨(dú)立。
線程同步機(jī)制失效:每個(gè)進(jìn)程有自己的線程鎖。
SharedPreferences可靠性下降:不支持并發(fā)寫,會(huì)出現(xiàn)臟數(shù)據(jù)。
Application多次創(chuàng)建:不同進(jìn)程跑在不同虛擬機(jī),每個(gè)虛擬機(jī)啟動(dòng)會(huì)創(chuàng)建自己的Application,自定義Application時(shí)生命周期會(huì)混亂。
綜上,不同進(jìn)程擁有各自獨(dú)立的虛擬機(jī),Application,內(nèi)存空間,由此引發(fā)一系列問(wèn)題。
第三: 進(jìn)程間通信
Bundle/Intent傳遞數(shù)據(jù):
可傳遞基本類型,String,實(shí)現(xiàn)了Serializable或Parcellable接口的數(shù)據(jù)結(jié)構(gòu)。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代碼量少(僅一句),但I(xiàn)/O開銷較大,一般用于輸出到磁盤或網(wǎng)卡;后者實(shí)現(xiàn)代碼多,效率高,一般用戶內(nèi)存間序列化和反序列化傳輸。
文件共享:
對(duì)同一個(gè)文件先后寫讀,從而實(shí)現(xiàn)傳輸,Linux機(jī)制下,可以對(duì)文件并發(fā)寫,所以要注意同步。順便一提,Windows下不支持并發(fā)讀或?qū)憽?/p>
Messenger:
Messenger是基于AIDL實(shí)現(xiàn)的,服務(wù)端(被動(dòng)方)提供一個(gè)Service來(lái)處理客戶端(主動(dòng)方)連接,維護(hù)一個(gè)Handler來(lái)創(chuàng)建Messenger,在onBind時(shí)返回Messenger的binder。
雙方用Messenger來(lái)發(fā)送數(shù)據(jù),用Handler來(lái)處理數(shù)據(jù)。Messenger處理數(shù)據(jù)依靠Handler,所以是串行的,也就是說(shuō),Handler接到多個(gè)message時(shí),就要排隊(duì)依次處理。
AIDL:
AIDL通過(guò)定義服務(wù)端暴露的接口,以提供給客戶端來(lái)調(diào)用,AIDL使服務(wù)器可以并行處理,而Messenger封裝了AIDL之后只能串行運(yùn)行,所以Messenger一般用作消息傳遞。
通過(guò)編寫aidl文件來(lái)設(shè)計(jì)想要暴露的接口,編譯后會(huì)自動(dòng)生成響應(yīng)的java文件,服務(wù)器將接口的具體實(shí)現(xiàn)寫在Stub中,用iBinder對(duì)象傳遞給客戶端,客戶端bindService的時(shí)候,用asInterface的形式將iBinder還原成接口,再調(diào)用其中的方法。
ContentProvider:
系統(tǒng)四大組件之一,底層也是Binder實(shí)現(xiàn),主要用來(lái)為其他APP提供數(shù)據(jù),可以說(shuō)天生就是為進(jìn)程通信而生的。自己實(shí)現(xiàn)一個(gè)ContentProvider需要實(shí)現(xiàn)6個(gè)方法,其中onCreate是主線程中回調(diào)的,其他方法是運(yùn)行在Binder之中的。自定義的ContentProvider注冊(cè)時(shí)要提供authorities屬性,應(yīng)用需要訪問(wèn)的時(shí)候?qū)傩园b成Uri.parse("content://authorities")。還可以設(shè)置permission,readPermission,writePermission來(lái)設(shè)置權(quán)限。 ContentProvider有query,delete,insert等方法,看起來(lái)貌似是一個(gè)數(shù)據(jù)庫(kù)管理類,但其實(shí)可以用文件,內(nèi)存數(shù)據(jù)等等一切來(lái)充當(dāng)數(shù)據(jù)源,query返回的是一個(gè)Cursor,可以自定義繼承AbstractCursor的類來(lái)實(shí)現(xiàn)。
Socket:
學(xué)過(guò)計(jì)算機(jī)網(wǎng)絡(luò)的對(duì)Socket不陌生,所以不需要詳細(xì)講述。只需要注意,Android不允許在主線程中請(qǐng)求網(wǎng)絡(luò),而且請(qǐng)求網(wǎng)絡(luò)必須要注意聲明相應(yīng)的permission。然后,在服務(wù)器中定義ServerSocket來(lái)監(jiān)聽(tīng)端口,客戶端使用Socket來(lái)請(qǐng)求端口,連通后就可以進(jìn)行通信。
主要講下Android如何使用MQTT通訊。用到的軟件或者框架有:
EMQ:
org.eclipse.paho的MQTT通訊框架:
如果已經(jīng)有MQTT相關(guān)服務(wù),可以跳過(guò)第一項(xiàng),從第二項(xiàng)開始看。
1.安裝所需要的依賴包
2.使用以下命令設(shè)置穩(wěn)定存儲(chǔ)庫(kù),以 CentOS7 為例
3.安裝最新版本的 EMQ X
4.安裝特定版本的 EMQ X
5.啟動(dòng) EMQ X
地址:xxx.xxx.xxx:18083,地址為服務(wù)器ip或者域名,端口為18083端口
1.在Android中導(dǎo)入依賴
項(xiàng)目地址:
2.創(chuàng)建MQTT連接的一個(gè)Service
本章節(jié) 比較簡(jiǎn)單
直接上code了
首先創(chuàng)建一個(gè)UDP class 構(gòu)造方法如下
通過(guò)newFixedThreadPool 創(chuàng)建一個(gè)線程池
然后
一個(gè)startUdp scoket 重要步驟
startSocketThread是一個(gè) 接收消息的子線程
內(nèi)部是一個(gè)接收消息的循環(huán)
BROADCAST_IP 是通信對(duì)方的地址
利用廣播 把接收到的消息打印到前臺(tái)
再然后創(chuàng)建一個(gè)發(fā)送message的方法
文章所有code 地址--- github
Android 進(jìn)程間通信的幾種實(shí)現(xiàn)方式
主要有4種方式:
這4種方式正好對(duì)應(yīng)于android系統(tǒng)中4種應(yīng)用程序組件:Activity、Content Provider、Broadcast和Service。
主要實(shí)現(xiàn)原理:
由于應(yīng)用程序之間不能共享內(nèi)存。為了在不同應(yīng)用程序之間交互數(shù)據(jù)(跨進(jìn)程通訊),Android?SDK中提供了4種用于跨進(jìn)程通訊的方式進(jìn)行交互數(shù)據(jù),實(shí)現(xiàn)進(jìn)程間通信主要是使用sdk中提供的4組組件根據(jù)實(shí)際開發(fā)情況進(jìn)行實(shí)現(xiàn)數(shù)據(jù)交互。
詳細(xì)實(shí)現(xiàn)方式:
Acitivity實(shí)現(xiàn)方式
Activity的跨進(jìn)程訪問(wèn)與進(jìn)程內(nèi)訪問(wèn)略有不同。雖然它們都需要Intent對(duì)象,但跨進(jìn)程訪問(wèn)并不需要指定Context對(duì)象和Activity的 Class對(duì)象,而需要指定的是要訪問(wèn)的Activity所對(duì)應(yīng)的Action(一個(gè)字符串)。有些Activity還需要指定一個(gè)Uri(通過(guò) Intent構(gòu)造方法的第2個(gè)參數(shù)指定)。 在android系統(tǒng)中有很多應(yīng)用程序提供了可以跨進(jìn)程訪問(wèn)的Activity,例如,下面的代碼可以直接調(diào)用撥打電話的Activity。
Intent?callIntent?=?new??Intent(Intent.ACTION_CALL,?Uri.parse("tel:12345678"?);??
startActivity(callIntent);
Content Provider實(shí)現(xiàn)方式
Android應(yīng)用程序可以使用文件或SqlLite數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)數(shù)據(jù)。Content Provider提供了一種在多個(gè)應(yīng)用程序之間數(shù)據(jù)共享的方式(跨進(jìn)程共享數(shù)據(jù))
應(yīng)用程序可以利用Content Provider完成下面的工作
1. 查詢數(shù)據(jù)
2. 修改數(shù)據(jù)
3. 添加數(shù)據(jù)
4. 刪除數(shù)據(jù)
Broadcast 廣播實(shí)現(xiàn)方式
廣播是一種被動(dòng)跨進(jìn)程通訊的方式。當(dāng)某個(gè)程序向系統(tǒng)發(fā)送廣播時(shí),其他的應(yīng)用程序只能被動(dòng)地接收廣播數(shù)據(jù)。這就象電臺(tái)進(jìn)行廣播一樣,聽(tīng)眾只能被動(dòng)地收聽(tīng),而不能主動(dòng)與電臺(tái)進(jìn)行溝通。在應(yīng)用程序中發(fā)送廣播比較簡(jiǎn)單。只需要調(diào)用sendBroadcast方法即可。該方法需要一個(gè)Intent對(duì)象。通過(guò)Intent對(duì)象可以發(fā)送需要廣播的數(shù)據(jù)。
Service?實(shí)現(xiàn)方式
常用的使用方式之一:利用AIDL Service實(shí)現(xiàn)跨進(jìn)程通信
這是我個(gè)人比較推崇的方式,因?yàn)樗啾菳roadcast而言,雖然實(shí)現(xiàn)上稍微麻煩了一點(diǎn),但是它的優(yōu)勢(shì)就是不會(huì)像廣播那樣在手機(jī)中的廣播較多時(shí)會(huì)有明顯的時(shí)延,甚至有廣播發(fā)送不成功的情況出現(xiàn)。
注意普通的Service并不能實(shí)現(xiàn)跨進(jìn)程操作,實(shí)際上普通的Service和它所在的應(yīng)用處于同一個(gè)進(jìn)程中,而且它也不會(huì)專門開一條新的線程,因此如果在普通的Service中實(shí)現(xiàn)在耗時(shí)的任務(wù),需要新開線程。
要實(shí)現(xiàn)跨進(jìn)程通信,需要借助AIDL(Android Interface Definition Language)。Android中的跨進(jìn)程服務(wù)其實(shí)是采用C/S的架構(gòu),因而AIDL的目的就是實(shí)現(xiàn)通信接口。
總結(jié)
跨進(jìn)程通訊這個(gè)方面service方式的通訊遠(yuǎn)遠(yuǎn)復(fù)雜于其他幾種通訊方式,實(shí)際開發(fā)中Activity、Content Provider、Broadcast和Service。4種經(jīng)常用到,學(xué)習(xí)過(guò)程中要對(duì)沒(méi)種實(shí)現(xiàn)方式有一定的了解。
一般都是使用一些傳輸協(xié)議,參考如下:
Android現(xiàn)在即時(shí)通訊(或者消息推送)有好幾個(gè)開源項(xiàng)目框架可以實(shí)現(xiàn),可以使用XMPP來(lái)實(shí)現(xiàn)即時(shí)通信。
XMPP(Extensible Messageing and Presence Protocol:可擴(kuò)展消息與存在協(xié)議)是目前主流的四種IM(IM:instant messaging,即時(shí)消息)協(xié)議之一,其他三種分別為:即時(shí)信息和空間協(xié)議(IMPP)、空間和即時(shí)信息協(xié)議(PRIM)、針對(duì)即時(shí)通訊和空間平衡擴(kuò)充的進(jìn)程開始協(xié)議SIP(SIMPLE)。
1. XMPP的前身是Jabber,一個(gè)開源形式組織產(chǎn)生的網(wǎng)絡(luò)即時(shí)通信協(xié)議。XMPP目前被IETF國(guó)際標(biāo)準(zhǔn)組織完成了標(biāo)準(zhǔn)化工作。標(biāo)準(zhǔn)化的核心結(jié)果分為兩部分; 核心的XML流傳輸協(xié)議 基于XML流傳輸?shù)募磿r(shí)通訊擴(kuò)展應(yīng)用 XMPP的核心XML流傳輸協(xié)議的定義使得XMPP能夠在一個(gè)比以往網(wǎng)絡(luò)通信協(xié)議更規(guī)范的平臺(tái)上。借助于XML易于解析和閱讀的特性,使得XMPP的協(xié)議能夠非常漂亮。 XMPP的即時(shí)通訊擴(kuò)展應(yīng)用部分是根據(jù)IETF在這之前對(duì)即時(shí)通訊的一個(gè)抽象定義的,與其他業(yè)已得到廣泛使用的即時(shí)通訊協(xié)議,諸如AIM,QQ等有功能完整,完善等先進(jìn)性。
2.XMPP中定義了三個(gè)角色,客戶端,服務(wù)器,網(wǎng)關(guān)。通信能夠在這三者的任意兩個(gè)之間雙向發(fā)生。服務(wù)器同時(shí)承擔(dān)了客戶端信息記錄,連接管理和信息的路由功能。網(wǎng)關(guān)承擔(dān)著與異構(gòu)即時(shí)通信系統(tǒng)的互聯(lián)互通,異構(gòu)系統(tǒng)可以包括SMS(短信),MSN,ICQ等?;镜木W(wǎng)絡(luò)形式是單客戶端通過(guò)TCP/IP連接到單服務(wù)器,然后在之上傳輸XML。
四大組件以及通訊機(jī)制:
activity
(1)一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕(窗口)。
(2)Activity之間通過(guò)Intent進(jìn)行通信。
(3)android應(yīng)用中每一個(gè)Activity都必須要在AndroidManifest.xml配置文件中聲明,否則系統(tǒng)將不識(shí)別也不執(zhí)行該Activity。
service
(1)service用于在后臺(tái)完成用戶指定的操作。service分為兩種:
(a)started(啟動(dòng)):當(dāng)應(yīng)用程序組件(如activity)調(diào)用startService()方法啟動(dòng)服務(wù)時(shí),服務(wù)處于started狀態(tài)。
(b)bound(綁定):當(dāng)應(yīng)用程序組件調(diào)用bindService()方法綁定到服務(wù)時(shí),服務(wù)處于bound狀態(tài)。
(2)startService()與bindService()區(qū)別:
(a)started service(啟動(dòng)服務(wù))是由其他組件調(diào)用startService()方法啟動(dòng)的,這導(dǎo)致服務(wù)的onStartCommand()方法被調(diào)用。當(dāng)服務(wù)是started狀態(tài)時(shí),其生命周期與啟動(dòng)它的組件無(wú)關(guān),并且可以在后臺(tái)無(wú)限期運(yùn)行,即使啟動(dòng)服務(wù)的組件已經(jīng)被銷毀。因此,服務(wù)需要在完成任務(wù)后調(diào)用stopSelf()方法停止,或者由其他組件調(diào)用stopService()方法停止。
(b)使用bindService()方法啟用服務(wù),調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出,服務(wù)也就終止,大有“不求同時(shí)生,必須同時(shí)死”的特點(diǎn)。
(3)開發(fā)人員需要在應(yīng)用程序配置文件中聲明全部的service,使用service/service標(biāo)簽。
(4)Service通常位于后臺(tái)運(yùn)行,它一般不需要與用戶交互,因此Service組件沒(méi)有圖形用戶界面。Service組件需要繼承Service基類。Service組件通常用于為其他組件提供后臺(tái)服務(wù)或監(jiān)控其他組件的運(yùn)行狀態(tài)。
content provider
(1)android平臺(tái)提供了Content Provider使一個(gè)應(yīng)用程序的指定數(shù)據(jù)集提供給其他應(yīng)用程序。其他應(yīng)用可以通過(guò)ContentResolver類從該內(nèi)容提供者中獲取或存入數(shù)據(jù)。
(2)只有需要在多個(gè)應(yīng)用程序間共享數(shù)據(jù)是才需要內(nèi)容提供者。例如,通訊錄數(shù)據(jù)被多個(gè)應(yīng)用程序使用,且必須存儲(chǔ)在一個(gè)內(nèi)容提供者中。它的好處是統(tǒng)一數(shù)據(jù)訪問(wèn)方式。
(3)ContentProvider實(shí)現(xiàn)數(shù)據(jù)共享。ContentProvider用于保存和獲取數(shù)據(jù),并使其對(duì)所有應(yīng)用程序可見(jiàn)。這是不同應(yīng)用程序間共享數(shù)據(jù)的唯一方式,因?yàn)閍ndroid沒(méi)有提供所有應(yīng)用共同訪問(wèn)的公共存儲(chǔ)區(qū)。
(4)開發(fā)人員不會(huì)直接使用ContentProvider類的對(duì)象,大多數(shù)是通過(guò)ContentResolver對(duì)象實(shí)現(xiàn)對(duì)ContentProvider的操作。
(5)ContentProvider使用URI來(lái)唯一標(biāo)識(shí)其數(shù)據(jù)集,這里的URI以content://作為前綴,表示該數(shù)據(jù)由ContentProvider來(lái)管理。
broadcast receiver
(1)你的應(yīng)用可以使用它對(duì)外部事件進(jìn)行過(guò)濾,只對(duì)感興趣的外部事件(如當(dāng)電話呼入時(shí),或者數(shù)據(jù)網(wǎng)絡(luò)可用時(shí))進(jìn)行接收并做出響應(yīng)。廣播接收器沒(méi)有用戶界面。然而,它們可以啟動(dòng)一個(gè)activity或serice來(lái)響應(yīng)它們收到的信息,或者用NotificationManager來(lái)通知用戶。通知可以用很多種方式來(lái)吸引用戶的注意力,例如閃動(dòng)背燈、震動(dòng)、播放聲音等。一般來(lái)說(shuō)是在狀態(tài)欄上放一個(gè)持久的圖標(biāo),用戶可以打開它并獲取消息。
(2)廣播接收者的注冊(cè)有兩種方法,分別是程序動(dòng)態(tài)注冊(cè)和AndroidManifest文件中進(jìn)行靜態(tài)注冊(cè)。
(3)動(dòng)態(tài)注冊(cè)廣播接收器特點(diǎn)是當(dāng)用來(lái)注冊(cè)的Activity關(guān)掉后,廣播也就失效了。靜態(tài)注冊(cè)無(wú)需擔(dān)憂廣播接收器是否被關(guān)閉,只要設(shè)備是開啟狀態(tài),廣播接收器也是打開著的。也就是說(shuō)哪怕app本身未啟動(dòng),該app訂閱的廣播在觸發(fā)時(shí)也會(huì)對(duì)它起作用。
網(wǎng)站標(biāo)題:android的通訊,android app之間通信
網(wǎng)頁(yè)地址:http://www.rwnh.cn/article30/dssdppo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、定制網(wǎng)站、Google、電子商務(wù)、外貿(mào)建站、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)