當前位置:首頁 » 安卓系統 » android通訊方式

android通訊方式

發布時間: 2023-03-02 08:25:01

Ⅰ Android網路通信都有哪幾種方式

Android網路編程分為兩種:基於http協議的,和基於socket的。
基於Http協議:HttpClient、HttpURLConnection、AsyncHttpClient框架等
基於Socket:
(1)針對TCP/IP的Socket、ServerSocket
(2)針對UDP/IP的DatagramSocket、DatagramPackage
(3)Apache Mina框架

Ⅱ Android通信方式篇(七)-Binder機制(Native層(下))

本篇文章針對向ServiceManager注冊服務 和 獲取服務兩個流程來做總結。在這兩個過程中,ServiceManager都扮演的是服務端,與客戶端之間的通信也是通過Binder IPC。

在此之前先了解下Binder的進程與線程的關系:

用戶空間 :ProcessState描述一個進程,IPCThreadState對應一個進程中的一個線程。
內核空間 :binder_proc描述一個進程,統一由binder_procs全局鏈表保存,binder_thread對應進程的一個線程。
ProcessState與binder_proc是一一對應的。

Binder線程池 :每個Server進程在啟動時會創建一個binder線程池,並向其中注冊一個Binder線程;之後Server進程也可以向binder線程池注冊新的線程,或者Binder驅動在探測到沒有空閑binder線程時會主動向Server進程注冊新的的binder線程。對於一個Server進程有一個最大Binder線程數限制15,(#define DEFAULT_MAX_BINDER_THREADS 15)。對於所有Client端進程的binder請求都是交由Server端進程的binder線程來處理的。我的理解是:binder線程是進程進行binder ipc時的一條數據處理路徑。

MediaPlayerService向ServiceManager注冊過程如下:

相關類:

整個過程總結如下:
1 獲取BpServiceManager 與 BpBinder
由defaultServiceManager()返回的是BpServiceManager,同時會創建ProcessState對象和BpBinder對象。然後通過BpBinder執行transact,把真正工作交給IPCThreadState來處理。

2 BpBinder transact
Binder代理類調用transact()方法,真正工作還是交給IPCThreadState來進行transact工作。

3 通過IPCThreadState 包裝並轉換數據並進行transact事務處理
每個線程都有一個IPCThreadState,每個IPCThreadState中都有一對Parcel變數:mIn、mOut。相當於兩根數據管道:

最後執行talkWithDriver。

writeTransactionData:將BC Protocol + binder_transaction_data結構體 寫入mOut, 然後執行waitForResponse:

由talkWithDriver將數據進一步封裝到binder_write_read結構體,通過ioctl(BINDER_WRITE_READ)與驅動通信。同時等待驅動返回的接收BR命令,從mIn取出返回的數據。

mIn包裝的數據結構(注冊服務handle = 0 ,code 為ADD_SERVICE_TRANSACTION):

4 Binder Driver
把binder_write_read結構體write_buffer里數據取出來,分別得到BC命令和封裝好數據的事務binder_transaction_data, 然後根據handler,在當前binder_proc中,找到相應的binder_ref,由binder_ref再找到目標binder_node實體,由目標binder_node再找到目標進程binder_proc。然後就是插入數據:當binder驅動可以找到合適的線程,就會把binder_transaction節點插入到servciemanager的線程的todo隊列中,如果找不到合適的線程,就把節點之間插入servciemanager的binder_proc的todo隊列。

5 ServiceManager
經過Binder Driver的處理,數據已經到了ServiceManager進程,在BR_TRANSACTION的引導下,在binder_loop()中執行binder_parser()取出數據,執行do_add_service()操作,最終向 svcinfo 列表中添加已經注冊的服務(沒有數據的返回)。最後發送 BR_REPLY 命令喚醒等待的線程,通知注冊成功。結束MediaPlayerService進程 waitForResponse()的狀態,整個注冊過程結束。

獲取服務的過程與注冊類似,首先 ServiceManager 向 Binder 驅動發送 BC_TRANSACTION 命令攜帶 CHECK_SERVICE_TRANSACTION 命令,同時獲取服務的線程進入等待狀態 waitForResponse()。Binder 驅動收到請求命令向 ServiceManager 的發送 BC_TRANSACTION 查詢已注冊的服務,會區分請求服務所屬進程情況。

查詢到直接響應 BR_REPLY 喚醒等待的線程。若查詢不到將與 binder_procs 鏈表中的服務進行一次通訊再響應。

以startService為例來簡單總結下執行流程:

3.1 從方法執行流程來看:

Client :

1 AMP.startService 標記方法以及通過Parcel包裝數據;

2 BinderProxy.transact 實際調用native的 android_os_BinderProxy_transact 傳遞數據;

3 獲取BpServiceManager 與 BpBinder 同時會創建ProcessState。然後通過BpBinder執行transact,把真正工作交給IPCThreadState來處理;

4 IPC.transact 主要執行writeTransactionData,將上層傳來的數據重新包裝成binder_transaction_data,並將BC Protocol + binder_transaction_data結構體 寫入mOut;

5 IPC waitForResponse talkWithDriver + 等待返回數據;

6 talkWithDriver 將數據進一步封裝成binder_write_read,通過ioctl(BINDER_WRITE_READ)與驅動通信;

Kernel :

7 binder ioctl 接收BINDER_WRITE_READ ioctl命令;

8 binder_ioctl_write_read 把用戶空間數據ubuf拷貝到內核空間bwr;

9 binder_thread_write 當bwr寫緩存有數據,則執行binder_thread_write;當寫失敗則將bwr數據寫回用戶空間並退出;

10 binder_transaction 找到目標進程binder_proc並插入數據到目標進程的線程todo隊列,最終執行到它
時,將發起端數據拷貝到接收端進程的buffer結構體;

11 binder_thread_read 根據binder_transaction結構體和binder_buffer結構體數據生成新的binder_transaction_data結構體,寫入bwr的read_buffer,當bwr讀緩存有數據,則執行binder_thread_read;當讀失敗則再將bwr數據寫回用戶空間並退出;最後,把內核數據bwr拷貝到用戶空間ubuf。

12 binder_thread_write + binder_ioctl BR命令和數據傳遞

Server:

13 IPC.executeCommand 解析kernel傳過來的binder_transaction_data數據,找到目標BBinder並調用其transact()方法;

14 IPC.joinThreadPool 採用循環不斷地執行getAndExecuteCommand()方法, 處理事務。當bwr的讀寫buffer都沒有數據時,則阻塞在binder_thread_read的wait_event過程. 另外,正常情況下binder線程一旦創建則不會退出.

15 BBinder.transact 到Binder.exeTransact 調用 AMN.onTransact

16 AMN.onTransact 把數據傳遞到AMS.starService去執行

17 AMS.starService Server處理了Client的請求了

然後原路replay回去,talkWithDriver 到Kernel ,然後找到Client進程,把數據拷貝到read_buffer里,最終喚醒IPC,把反饋傳遞回AMP.startService。完成啟動服務。

3.2 從通信協議流程來看:

非oneWay:

oneway:

oneway與非oneway區別: 都是需要等待Binder Driver的回應消息BR_TRANSACTION_COMPLETE. 主要區別在於oneway的通信收到BR_TRANSACTION_COMPLETE則返回,而不會再等待BR_REPLY消息的到來. 另外,oneway的binder IPC則接收端無法獲取對方的pid.

3.3 從數據流來看

從用戶空間開始:

進入驅動後:

回到用戶空間:

參考:
http://gityuan.com/2016/09/04/binder-start-service/
http://gityuan.com/2015/11/28/binder-summary/
http://gityuan.com/2015/11/14/binder-add-service/
http://gityuan.com/2015/11/15/binder-get-service/

Ⅲ Flutter與Android通信的三種方式

一、 MethodChannel
主要是flutter端調用android方法。flutter調取android方法,也可以android主動跟flutter通信,但是這個只能是傳遞數據,不是調方法。MethodChannel的flutter調取android方法,我之前寫過,可以查看如下鏈接, https://www.jianshu.com/p/6b677ff3350e

Android主動跟flutter通信,如下

二、 BasicMessageChannel
它是可以雙端通信的,flutter端可以給Android發送消息,Android也可以給Flutter發送消息。

三、EventChannel
只能是原生發送消息給Flutter端,例如監聽手機電量變化,網路變化,感測器等。

列印結果如下:

總結一下:
MethodChannel 用於傳遞方法調用(method invocation),是flutter調取原生方法的,也可以原生主動傳遞數據給Flutter。
BasicMessageChannel 用於傳遞字元串和半結構化的信息。是兩個端相互發送數據,接收數據的。
EventChannel 用於數據流(event streams)的通信。通長用於Nativie向flutter的通信,如:手機電量變化,網路連接變化,陀螺儀,感測器等;

tip:多種類型的通道混用可能會出現報錯問題。

Ⅳ 了解Android進程間通信的四種方式

由於應用程序之間不能共享內存。在不同應用程序之間交互數據(跨進程通訊),在android 

SDK中提供了4種用於跨進程通訊的方式。這4種方式正好對應於android系統中4種應用程序組

件:Activity、Content Provider、Broadcast和Service。其中Activity可以跨進程調用其他應

用程序的Activity;Content Provider可以跨進程訪問其他應用程序中的數據(以Cursor對象形

式返回),當然,也可以對其他應用程序的數據進行增、刪、改操 作;Broadcast可以向

android系統中所有應用程序發送廣播,而需要跨進程通訊的應用程序可以監聽這些廣播;

Service和Content Provider類似,也可以訪問其他應用程序中的數據,但不同的是,Content 

Provider返回的是Cursor對象,而Service返回的是java對象,這種可以跨進程通訊的服務叫

AIDL服務。

Ⅳ android進程間通訊方式有哪些

Android中實現不同應用進程間通訊,需要用到AIDL技術,以下為AIDL服務端和客戶端實現步驟:

一、服務端:
1、在AndroidManifest.xml中定義的包路徑下新建一個文件,擴展名為.aidl(如:IXxxService.aidl),系統會在gen中自動生成對應的.java文件(如:IXxxService.java)
2、在aidl文件中編寫介面方法,語法同java區別不大。注意:方法參數支持java基本類型(int、long、boolean等)和(String、List、Map、CharSequence)
其它復雜類型需要自定義(實現Parcelable.Creator介面及其方法)。
3、在包路徑新建一個繼承 android.app.Service 的服務類,在該類中定義繼承 IXxxService.Stub 抽象類的內部類並實現抽象方法,如:

[java] view plainprint?

public class XxxService extends Service {
public class XxxServiceImpl extends IXxxService.Stub {
//implements methods
...

}

@Override
public IBinder onBind(Intent intent) {
XxxServiceImpl impl = new XxxServiceImpl();
return impl; //必須返回 XxxServiceImpl 的實例
}
}

4、在AndroidManifest.xml中注冊上面定義的服務

[java] view plainprint?

<!-- 注冊服務 -->
<service android:name="包路徑.XxxService" >
<intent-filter>
<!-- 指定調用AIDL服務的ID -->
<action android:name="包路徑.IXxxService" />
</intent-filter>
</service>

二、客戶端
1、將服務端中自動生成的IXxxService.java文件拷貝到客戶端工程,注意:文件所在包路徑必須和服務端完全一致。
2、服務可以封裝成幫助類調用,也可以直接在Activity中調用,後者如:

[java] view plainprint?

// Activity 中聲明服務介面變數
private IXxxService serviceInterface;

// Activity onCreate()方法中創建ServiceConnection對象,並初始化serviceInterface
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 獲得AIDL服務對象
serviceInterface = IXxxService.Stub.asInterface(service);
}

@Override
public void onServiceDisconnected(ComponentName name) {
}
};

// 綁定服務,AIDL_SERVICE_ID 為 "一、服務端 4、" 中提到的「指定調用AIDL服務的ID」
bindService(new Intent(AIDL_SERVICE_ID), serviceConnection, Context.BIND_AUTO_CREATE);

注意:在Activity 的 onDestory 方法中調用解除綁定服務的方法:unbindService(serviceConnection);

3、在按鈕點擊等事件中就可以調用服務中定義的方法了,如:serviceInterface.xxxMethod();

注意:服務端 XxxService 不能定義為單例的,否則無法調用

Ⅵ android開發中跨進程通信有幾種方式

  • 在android SDK中提供了4種用於跨進程通訊的方式,Activity、Content Provider、Broadcast和Service。

  • 介紹

  1. Activity可以跨進程調用其他應用程序;

  2. Content Provider可以跨進程訪問其他應用程序中的數據;

  3. Broadcast可以向android系統中所有應用程序發送廣播;

  4. Content Provider返回的是Cursor對象,而Service返回的是Java對象,這種可以跨進程通訊的服務叫AIDL服務;

Ⅶ Carson帶你學Android:全面剖析Binder跨進程通信原理

從而全方位地介紹 Binder ,希望你們會喜歡。

在本文的講解中,按照 大角度 -> 小角度 去分析 Binder ,即:

從而全方位地介紹 Binder ,希望你們會喜歡。

在講解 Binder 前,我們先了解一些 Linux 的基礎知識

具體請看文章: 操作系統:圖文詳解 內存映射

Binder 跨進程通信機制 模型 基於 Client - Server 模式

此處重點講解 Binder 驅動作用中的跨進程通信的原理:

原因:

所以,原理圖可表示為以下:

所以,在進行跨進程通信時,開發者只需自定義 Client & Server 進程 並 顯式使用上述3個步驟,最終藉助 Android 的基本架構功能就可完成進程間通信

注冊服務後, Binder 驅動持有 Server 進程創建的 Binder 實體

此時, Client 進程與 Server 進程已經建立了連接

Client 進程 根據獲取到的 Service 信息( Binder 代理對象),通過 Binder 驅動 建立與 該 Service 所在 Server 進程通信的鏈路,並開始使用服務

步驟1: Client 進程 將參數(整數a和b)發送到 Server 進程

步驟2: Server 進程根據 Client 進要求 調用 目標方法(即加法函數)

步驟3: Server 進程 將目標方法的結果(即加法後的結果)返回給 Client 進程

對比 Linux ( Android 基於 Linux )上的其他進程通信方式(管道、消息隊列、共享內存、
信號量、 Socket ), Binder 機制的優點有:

特別地,對於從模型結構組成的Binder驅動來說:

不定期分享關於 安卓開發 的干貨,追求 短、平、快 ,但 卻不缺深度

Ⅷ android開發中跨進程通信有幾種方式

Android進程間通信的幾種方式 定義多進程
第一:Android應用中使用多進程只有一個辦法(用NDK的fork來做除外),就是在AndroidManifest.xml中聲明組件時,用android:process屬性來指定。
不知定process屬性,則默認運行在主進程中,主進程名字為包名。
android:process = package:remote,將運行在package:remote進程中,屬於全局進程,其他具有相同shareUID與簽名的APP可以跑在這個進程中。
android:process = :remote ,將運行在默認包名:remote進程中,而且是APP的私有進程,不允許其他APP的組件來訪問。
第二:多進程引發的問題
靜態成員和單例失效:每個進程保持各自的靜態成員和單例,相互獨立。
線程同步機制失效:每個進程有自己的線程鎖。
SharedPreferences可靠性下降:不支持並發寫,會出現臟數據。
Application多次創建:不同進程跑在不同虛擬機,每個虛擬機啟動會創建自己的Application,自定義Application時生命周期會混亂。
綜上,不同進程擁有各自獨立的虛擬機,Application,內存空間,由此引發一系列問題。
第三: 進程間通信
Bundle/Intent傳遞數據:
可傳遞基本類型,String,實現了Serializable或Parcellable介面的數據結構。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代碼量少(僅一句),但I/O開銷較大,一般用於輸出到磁碟或網卡;後者實現代碼多,效率高,一般用戶內存間序列化和反序列化傳輸。
文件共享:
對同一個文件先後寫讀,從而實現傳輸,Linux機制下,可以對文件並發寫,所以要注意同步。順便一提,Windows下不支持並發讀或寫。
Messenger:
Messenger是基於AIDL實現的,服務端(被動方)提供一個Service來處理客戶端(主動方)連接,維護一個Handler來創建Messenger,在onBind時返回Messenger的binder。
雙方用Messenger來發送數據,用Handler來處理數據。Messenger處理數據依靠Handler,所以是串列的,也就是說,Handler接到多個message時,就要排隊依次處理。
AIDL:
AIDL通過定義服務端暴露的介面,以提供給客戶端來調用,AIDL使伺服器可以並行處理,而Messenger封裝了AIDL之後只能串列運行,所以Messenger一般用作消息傳遞。
通過編寫aidl文件來設計想要暴露的介面,編譯後會自動生成響應的java文件,伺服器將介面的具體實現寫在Stub中,用iBinder對象傳遞給客戶端,客戶端bindService的時候,用asInterface的形式將iBinder還原成介面,再調用其中的方法。
ContentProvider:
系統四大組件之一,底層也是Binder實現,主要用來為其他APP提供數據,可以說天生就是為進程通信而生的。自己實現一個ContentProvider需要實現6個方法,其中onCreate是主線程中回調的,其他方法是運行在Binder之中的。自定義的ContentProvider注冊時要提供authorities屬性,應用需要訪問的時候將屬性包裝成Uri.parse("content://authorities")。還可以設置permission,readPermission,writePermission來設置許可權。 ContentProvider有query,delete,insert等方法,看起來貌似是一個資料庫管理類,但其實可以用文件,內存數據等等一切來充當數據源,query返回的是一個Cursor,可以自定義繼承AbstractCursor的類來實現。
Socket:
學過計算機網路的對Socket不陌生,所以不需要詳細講述。只需要注意,Android不允許在主線程中請求網路,而且請求網路必須要注意聲明相應的permission。然後,在伺服器中定義ServerSocket來監聽埠,客戶端使用Socket來請求埠,連通後就可以進行通信。

熱點內容
加密ovpn 發布:2025-05-12 12:01:55 瀏覽:43
python練手項目 發布:2025-05-12 11:14:07 瀏覽:122
壓縮聽算音頻 發布:2025-05-12 10:58:12 瀏覽:801
資料庫系統報告 發布:2025-05-12 10:43:17 瀏覽:603
日產高配有哪些配置 發布:2025-05-12 10:32:16 瀏覽:475
大眾朗逸哪個配置值得入手 發布:2025-05-12 10:31:20 瀏覽:505
壓縮包的後綴 發布:2025-05-12 10:20:35 瀏覽:942
煙台招聘編程 發布:2025-05-12 10:04:21 瀏覽:53
sql查詢所有表名 發布:2025-05-12 10:01:28 瀏覽:666
用python編譯器的簡單代碼 發布:2025-05-12 09:48:40 瀏覽:358