新聞中心
Android跨進程通信
Android 為我們提供了以下幾種進程通信機制(供開發(fā)者使用的進程通信 API)對應的文章鏈接如下:
我們注重客戶提出的每個要求,我們充分考慮每一個細節(jié),我們積極的做好網(wǎng)站設計制作、成都網(wǎng)站制作服務,我們努力開拓更好的視野,通過不懈的努力,創(chuàng)新互聯(lián)公司贏得了業(yè)內(nèi)的良好聲譽,這一切,也不斷的激勵著我們更好的服務客戶。 主要業(yè)務:網(wǎng)站建設,網(wǎng)站制作,網(wǎng)站設計,微信小程序定制開發(fā),網(wǎng)站開發(fā),技術開發(fā)實力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫的技術開發(fā)工程師。
Android 進階:進程通信之 Binder 機制淺析
Android 進階:進程通信之 AIDL 解析
Android MQTT 通信
??MQTT 協(xié)議 是基于發(fā)布/訂閱模式的物聯(lián)網(wǎng)通信協(xié)議,憑借簡單易實現(xiàn)、支持 QoS、報文小等特點,占據(jù)了物聯(lián)網(wǎng)協(xié)議的半壁江山。
??常用于 IOT 物聯(lián)網(wǎng)和一些需要服務端主動通知客戶端的場景。
1. 導入依賴
2. 創(chuàng)建 MqttHelper 輔助類,設置回調監(jiān)聽
3. 連接 MQTT
??連接成功或失敗,以及中途的連接掉線,會觸發(fā) OnMqttStatusChangeListener 回調
4. MQTT 連接狀態(tài)監(jiān)聽
5. MQTT 收發(fā)消息監(jiān)聽
??onSubMessage 訂閱的消息回調,因為存在訂閱多個 topic 的情況,所以回調能知道是來自哪個 Topic 的消息;
??onPubMessage 發(fā)布的消息回調,用于確認發(fā)布的消息是否發(fā)送成功。
6. MQTT 訂閱 Topic
??需要在 MQTT 連接成功后才能訂閱 topic,否則訂閱 Topic 不成功,收不到對應消息
7. MQTT 取消訂閱 Topic
8. MQTT 發(fā)布消息
9. MQTT 斷開連接
10. 通知設置
??由于 MQTT 啟動了一個 Service,而 Android 8.0 以上對于后臺 Service 限制時長 5 秒;所以將 MqttService 綁定到 Notification 上成為了一個前臺通知;通知的標題和內(nèi)容顯示可以在 strings.xml 中設置,對應屬性如下:
??Android 8.0 及以上開啟前臺服務綁定到通知,8.0 以下默認不啟用,可將 mqtt_foreground_notification_low_26 設為 true,將 8.0 以下設備也開啟前臺通知服務
??創(chuàng)建 MQTT 實例時需要傳送參數(shù) MqttOptions,下面將介紹下部分參數(shù);
1. Topic
??MQTT 是一種發(fā)布/訂閱的消息協(xié)議, 通過設定的主題 Topic,
發(fā)布者向 Topic 發(fā)送的 payload 負載消息會經(jīng)過服務器, 轉發(fā)到所有訂閱
該 Topic 的訂閱者
?? 通配符 : 假想移動端消息推送場景,有的系統(tǒng)消息是全體用戶接收,有的消息是 Android 或 iOS 設備接收, 又或者是某些消息具體推送到用戶,當然, 對應的多種類型消息可以通過多訂閱幾個對應的 Topic 解決,也可以使用通配符;
??通配符有兩個, " + " 和 " # ", 與正斜杠 " / " 組合使用;加號只能表示一級Topic, 井號可以表示任意層級 Topic; 例如: 訂閱 Topic為 " System/+ ", 發(fā)布者發(fā)布的 Topic 可以是 System、System/Android、System/iOS; 但是不能是 System/iOS/123, 而訂閱的 Topic 如果是" System/# " 則可以收到;
?? 注意,只有訂閱的 Topic 才可以使用 通配符, 發(fā)布和遺囑的 Topic 不能包含通配符.
2. ClientID
??發(fā)布者和訂閱者都是屬于客戶端, 客戶端與服務端建立連接之后,發(fā)送的第一個報文消息必須是 Connect 消息,而 Connect 的消息載荷中必須包含 clientID 客戶端唯一標識;
??如果兩個客戶端的 clientID 一樣, 則服務端記錄第一個客戶端連接之后再收到第二個客戶端連接請求,則會向一個客戶端發(fā)送 Disconnect 報文斷開連接, 并連接第二個客戶端, 而如果此時設置了自動重連, 第一個客戶端再次連接,服務端又斷開與第二個的連接, 連上第一個客戶端, 如此將導致兩個客戶端不斷的被擠掉重連.
??注意: clientID 使用的字符最好是 大小寫字母和數(shù)字, 長度最好限制在[1, 23] 之間;
3. 遺囑消息
??可選參數(shù), 客戶端沒有主動向服務端發(fā)起 disconnect 斷開連接消息,然而服務端檢測到和客戶端之間的連接已斷開, 此時服務端將該客戶端設置的遺囑消息發(fā)送出去
??應用場景: 客戶端因網(wǎng)絡等情況掉線之后, 可以及時通知到所有訂閱該遺囑 Topic 的客戶端;
??遺囑 Topic 中不能存在通配符.
4. Session
??客戶端和服務端之間建立的會話狀態(tài), 一般用于消息保存, 如果設置清除 Session,則每次客戶端和服務端建立連接會創(chuàng)建一個新的會話,之前連接中的消息不能恢復,
??而設置不清除會話, 對應發(fā)布者發(fā)送的 qos 為 1和2 的消息,還未被訂閱者接收確認,則需要保存在會話中, 以便訂閱者下次連接可以恢復這些消息;
??注意: Session 存儲的消息是保存在內(nèi)容中的, 所以如果不是重要的消息,最好是設置清除 Session, 或者設置 qos = 0;
5. 心跳包
??標識客戶端傳輸一次控制報文到下一次傳輸之間允許的空閑時間;在這段時間內(nèi),如果客戶端沒有其他任何報文發(fā)送,必須發(fā)送一個 PINGREQ 報文到服務器,而如果服務端在 1.5 倍心跳時間內(nèi)沒有收到客戶端消息,則會主動斷開客戶端的連接,發(fā)送其遺囑消息給所有訂閱者。而服務端收到 PINGREQ 報文之后,立即返回 PINGRESP 報文給客戶端
??心跳時間單位為秒,占用2個字節(jié),最大 2^16 - 1 = 65535秒(18小時12分鐘15秒),設置為 0 表示不使用心跳機制; 心跳時間一般設置為幾分鐘或幾十秒即可,時間短點可以更快的發(fā)出遺囑消息通知掉線,但是時間短會增加消息頻率,影響服務端并發(fā); 微信長連接為 300 秒,而三大運營商貌似也有個連接時間最小的為 5 分鐘。
6. qos
??服務質量等級 qos 對應兩部分,一是客戶端到服務端發(fā)送的消息, 一是服務端到客戶端訂閱的消息; 從發(fā)布者到訂閱者實際 qos 為兩段路中 qos 最小的。
??qos 可選值 0(最多交付一次)、1(最少交付一次)、2(正好交付一次);
?? qos = 0 :接收方不發(fā)送響應,發(fā)送方不進行重試;發(fā)送方只管發(fā)一次,不管是否發(fā)成功,也不管接收方是否成功接收,適用于不重要的數(shù)據(jù)傳輸;
?? qos = 1 :確保消息至少有一次到達接收方,發(fā)送方向接收方發(fā)送消息,需要等待接收方返回應答消息,如果發(fā)送方在一定時間之內(nèi)沒有收到應答,發(fā)送方繼續(xù)下一次消息發(fā)送,直到收到應答消息,刪除本地消息緩存,不再發(fā)送;所以接收方可能收到1-n次消息;適用于需要收到所有消息,客戶端可以處理重復消息。
?? qos = 2 :確保消息只一次到達接收方,發(fā)送方和接收方之間消息處理流程最復雜;
?? Mqtt Qos 深度解讀 和 MQTT協(xié)議QoS2 準確一次送達的實現(xiàn)
7. payload 負載消息
??字節(jié)流類型, 是 MQTT 通信傳輸?shù)恼鎸崝?shù)據(jù)
8. 保留消息
??發(fā)布消息時設置, 對應參數(shù) retain, 服務端將保留對應 Topic 最新的一條消息記錄; 保留消息的作用是每次客戶端連接上線都會收到其 Topic 的最后一條保留消息, 所以可能存在網(wǎng)絡不穩(wěn)定,頻繁掉線重連,每次重連重復收到保留消息;
?? 可以向對應的 Topic 發(fā)送一條 空消息,用于清除保留消息。
MQTT 服務搭建 Apache Apollo 服務器 搭建 MQTT 服務
Github 倉庫
mqtt 協(xié)議
了解Android進程間通信的四種方式
由于應用程序之間不能共享內(nèi)存。在不同應用程序之間交互數(shù)據(jù)(跨進程通訊),在android?
SDK中提供了4種用于跨進程通訊的方式。這4種方式正好對應于android系統(tǒng)中4種應用程序組
件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨進程調用其他應
用程序的Activity;Content Provider可以跨進程訪問其他應用程序中的數(shù)據(jù)(以Cursor對象形
式返回),當然,也可以對其他應用程序的數(shù)據(jù)進行增、刪、改操 作;Broadcast可以向
android系統(tǒng)中所有應用程序發(fā)送廣播,而需要跨進程通訊的應用程序可以監(jiān)聽這些廣播;
Service和Content Provider類似,也可以訪問其他應用程序中的數(shù)據(jù),但不同的是,Content?
Provider返回的是Cursor對象,而Service返回的是Java對象,這種可以跨進程通訊的服務叫
AIDL服務。
Android進程間和線程間通信方式
? 進程:是具有一定獨立功能的程序關于某個數(shù)據(jù)集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調度的一個獨立單位。
??線程:是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己基本上不擁有系統(tǒng)資源,只擁有一些在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。
??區(qū)別:
??(1)、一個程序至少有一個進程,一個進程至少有一個線程;
??(2)、線程的劃分尺度小于進程,使得多線程程序的并發(fā)性高;
??(3)、進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉。
---------------------
一、Android進程間通信方式
1.Bundle
??由于Activity,Service,Receiver都是可以通過Intent來攜帶Bundle傳輸數(shù)據(jù)的,所以我們可以在一個進程中通過Intent將攜帶數(shù)據(jù)的Bundle發(fā)送到另一個進程的組件。
??缺點:無法傳輸Bundle不支持的數(shù)據(jù)類型。
2.ContentProvider
??ContentProvider是Android四大組件之一,以表格的方式來儲存數(shù)據(jù),提供給外界,即Content Provider可以跨進程訪問其他應用程序中的數(shù)據(jù)。用法是繼承ContentProvider,實現(xiàn)onCreate,query,update,insert,delete和getType方法,onCreate是負責創(chuàng)建時做一些初始化的工作,增刪查改的方法就是對數(shù)據(jù)的查詢和修改,getType是返回一個String,表示Uri請求的類型。注冊完后就可以使用ContentResolver去請求指定的Uri。
3.文件
??兩個進程可以到同一個文件去交換數(shù)據(jù),我們不僅可以保存文本文件,還可以將對象持久化到文件,從另一個文件恢復。要注意的是,當并發(fā)讀/寫時可能會出現(xiàn)并發(fā)的問題。
4.Broadcast
??Broadcast可以向android系統(tǒng)中所有應用程序發(fā)送廣播,而需要跨進程通訊的應用程序可以監(jiān)聽這些廣播。
5.AIDL方式
??Service和Content Provider類似,也可以訪問其他應用程序中的數(shù)據(jù),Content Provider返回的是Cursor對象,而Service返回的是Java對象,這種可以跨進程通訊的服務叫AIDL服務。
? ? ?AIDL通過定義服務端暴露的接口,以提供給客戶端來調用,AIDL使服務器可以并行處理,而Messenger封裝了AIDL之后只能串行運行,所以Messenger一般用作消息傳遞。
6.Messenger
??Messenger是基于AIDL實現(xiàn)的,服務端(被動方)提供一個Service來處理客戶端(主動方)連接,維護一個Handler來創(chuàng)建Messenger,在onBind時返回Messenger的binder。
??雙方用Messenger來發(fā)送數(shù)據(jù),用Handler來處理數(shù)據(jù)。Messenger處理數(shù)據(jù)依靠Handler,所以是串行的,也就是說,Handler接到多個message時,就要排隊依次處理。
7.Socket
??Socket方法是通過網(wǎng)絡來進行數(shù)據(jù)交換,注意的是要在子線程請求,不然會堵塞主線程??蛻舳撕头斩私⑦B接之后即可不斷傳輸數(shù)據(jù),比較適合實時的數(shù)據(jù)傳輸
二、Android線程間通信方式
??一般說線程間通信主要是指主線程(也叫UI線程)和子線程之間的通信,主要有以下兩種方式:
1.AsyncTask機制
??AsyncTask,異步任務,也就是說在UI線程運行的時候,可以在后臺的執(zhí)行一些異步的操作;AsyncTask可以很容易且正確地使用UI線程,AsyncTask允許進行后臺操作,并在不顯示使用工作線程或Handler機制的情況下,將結果反饋給UI線程。但是AsyncTask只能用于短時間的操作(最多幾秒就應該結束的操作),如果需要長時間運行在后臺,就不適合使用AsyncTask了,只能去使用Java提供的其他API來實現(xiàn)。
2.Handler機制
??Handler,繼承自Object類,用來發(fā)送和處理Message對象或Runnable對象;Handler在創(chuàng)建時會與當前所在的線程的Looper對象相關聯(lián)(如果當前線程的Looper為空或不存在,則會拋出異常,此時需要在線程中主動調用Looper.prepare()來創(chuàng)建一個Looper對象)。使用Handler的主要作用就是在后面的過程中發(fā)送和處理Message對象和讓其他的線程完成某一個動作(如在工作線程中通過Handler對象發(fā)送一個Message對象,讓UI線程進行UI的更新,然后UI線程就會在MessageQueue中得到這個Message對象(取出Message對象是由其相關聯(lián)的Looper對象完成的),并作出相應的響應)。
三、Android兩個子線程之間通信
??面試的過程中,有些面試官可能會問Android子線程之間的通信方式,由于絕大部分程序員主要關注的是Android主線程和子線程之間的通信,所以這個問題很容易讓人懵逼。
??主線程和子線程之間的通信可以通過主線程中的handler把子線程中的message發(fā)給主線程中的looper,或者,主線程中的handler通過post向looper中發(fā)送一個runnable。但looper默認存在于main線程中,子線程中沒有Looper,該怎么辦呢?其實原理很簡單,把looper綁定到子線程中,并且創(chuàng)建一個handler。在另一個線程中通過這個handler發(fā)送消息,就可以實現(xiàn)子線程之間的通信了。
??子線程創(chuàng)建handler的兩種方式:
??方式一:給子線程創(chuàng)建Looper對象:
new Thread(new Runnable() {
? ? ? ? public void run() {?
? ? ? ? ? ? Looper.prepare();? // 給這個Thread創(chuàng)建Looper對象,一個Thead只有一個Looper對象
? ? ? ? ? ? Handler handler = new Handler(){?
? ? ? ? ? ? ? ? @Override?
? ? ? ? ? ? ? ? public void handleMessage(Message msg) {?
? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? };?
? ? ? ? ? ? handler.sendEmptyMessage(1);?
? ? ? ? ? ? Looper.loop(); // 不斷遍歷MessageQueue中是否有消息
? ? ? ? };?
? ? }).start();
---------------------
? ?方式二:獲取主線程的looper,或者說是UI線程的looper:
new Thread(new Runnable() {
? ? ? ? public void run() {?
? ? ? ? ? ? Handler handler = new Handler(Looper.getMainLooper()){ // 區(qū)別在這?。。?
? ? ? ? ? ? ? ? @Override?
? ? ? ? ? ? ? ? public void handleMessage(Message msg) {?
? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "handleMessage", Toast.LENGTH_LONG).show();?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? };?
? ? ? ? ? ? handler.sendEmptyMessage(1);?
? ? ? ? };?
? ? }).start();
---------------------
網(wǎng)站名稱:android通信,android通信框架
本文鏈接:http://fisionsoft.com.cn/article/dsdiejh.html