Android IPCプロセス間通信実現理解


AndroidのIPC(プロセス間通信)にBinderメカニズムが採用されていることはよく知られていますが、プロセス間通信がどのように実現されているかを理解するには、Binderメカニズムを理解することが重要です.
まず、なぜAndroidのIPCはBinderメカニズムを採用するのか、資料を調べてみると、Binderメカニズムの利点はコピープロセスが1回少ないことであり、従来のIPCでは送信側を
送信されたデータは、ユーザ空間copyからカーネル空間へ、受信者への送信時にカーネル空間copyから受信者へ、IPC要求1回に2回のコピーが必要であり、Binderメカニズム
異なる時にただ1つのcopy操作をして、IPCの要求を発送して、Clientの端の携帯するデータのcopyをカーネルの空間に着くことができて、共有メモリの中で置いて、カーネルとユーザーの空間の内を通じて(通って)
ストレージは同じ物理空間にマッピングされ、カーネル空間copyから
ユーザースペース、このようなメカニズムはIPCの性能を高めました.
次に、Binderメカニズムの構成:
1)ユーザースペース:
Client:IPC要求を開始し、サービスマネージャから取得したサービスプロセスBinderエージェントオブジェクトの参照により、サービスに関するメソッドを呼び出します(サービスインタフェースはAIDLファイルで定義またはカスタムインタフェースクラスを使用できます).
Service:サービスインタフェース、Publish ServiceのBinderオブジェクトを含むAIDLのStubクラスを実装するには、ServiceManagerに登録する必要があります.
ServiceManager:システム内のサービスを管理し、サービスのBinderオブジェクトの参照を維持し、Clientにサービスを名前で照会するサービスインタフェースおよびサービスを提供する
のBinderオブジェクト参照
2)カーネルスペース:
Binderドライバ:プロセス間のデータの転送を担当し、mmapメモリマッピングにより共有メモリを実現し、Client側とServer側を接続する
実は個人的にBinderメカニズムの原理は大体いくつか理解してokになったと思って、結局Binderメカニズムの大多数の時修正する必要がないため、肝心なのはBinderメカニズムを理解する基礎の上で
Binderメカニズムに基づいてIPCを実現する方法と,AndroidシステムにおけるIPCの実現を理解し,プロセス間通信の問題を解決する方法.
CodeからBinderの具体的な実装を詳細に理解する場合は、以下のblogを参照して詳細な学習を行うことができます.
1.Android Banderの設計と実現-設計編
2.サービスマネージャがAndroidプロセス間通信(IPC)メカニズムBinderデーモンプロセスの道となる
Android FrameworkではIPCが必要な場所がたくさんあります.例えばstartActivityは、アプリでstartActivityを呼び出します.これは、アプリが一般的に走っているため、IPCリクエストを開始しました.
独自のプロセスで、ActivityManagerSerive(AMS)はsystem_で実行されます.serverプロセスでは、ここでActivityを起動するリクエストはIPCリクエストであり、APPプロセスはこのリクエストを送信します.
AMSが存在するプロセスに送り、AMSのstartActivityサービスを要求することで起動したいactivityを起動します.
IPC通信を実現する際、各プロセスは独自のBinderクラスを定義し、Binderオブジェクトを作成します.一般的にBinderエンティティオブジェクトはServerプロセスに存在しますが、Clientプロセスは
Binderメカニズムによるサービス要求は、サーバプロセスにおけるBinderプロキシオブジェクトの参照をServiceManagerで取得する必要があります.
Binderオブジェクトの実現は重要で煩雑であるため、開発者がIPCの開発を容易にするために、Androidが提供するAIDL(Android Interface Definition Language)インタフェース定義言語は、
ADTのaidlツールはAIDLで書かれたXXXに従う.aidlファイルは自動的に対応するインタフェースクラスを生成し、インタフェースクラスはandroidを継承する.os.StubとProxyの2つの内部クラスを含むIinterface
それぞれの役割は
インタフェースクラス:例えばIServiceAIDL.aidlは、生成するインタフェースクラスがIServiceAIDLである.JAva、androidから継承します.os.Iinterface、XXXに含む.aidlファイルで定義されているすべてのインタフェース
Stubクラス:サーバプロセス用、抽象クラス、androidから継承する.os.Binder,implements IServiceAIDLインタフェース,ServerプロセスにおけるBinderオブジェクトのタイプ,すなわちServerプロセスのCode
このBinderクラスを具体的に実装し、その中のインタフェースを具体的に実装し、このクラスから継承されたサブクラスまたは直接匿名クラス実装に対応するインタフェースを定義します.このようなインタフェースにはonTransactメソッドが含まれています.
このメソッドはBinderによってコールバックされ、入力されたインタフェースコード(intコード)に基づいて、サーバプロセスを呼び出す必要があるインタフェースを見つけます.
Proxyクラス:Clientプロセス用、implements IServiceAIDLインタフェースクラス、このインタフェースクラスのすべての方法を実現します.これはStubクラスの内部クラス、ServerプロセスBinderクラスのエージェントオブジェクト、Clientです.
Proxyのインタフェース(すなわちXXX.aidlファイルで定義されたサービスインタフェース)を呼び出し、Proxyのインタフェースの実装は最終的にIBinderのtransactメソッドを呼び出すことによってBinderドライバの実
現在のプロセスでは、Binderドライバ処理が完了し、すなわち、コールバックStubクラスのonTransactメソッドがサーバのサービス実装を呼び出す
ここでは、なぜインタフェースを定義するのか、プロセス間の通信はターゲットプロセスのサービスにほかならないが、プログラムを緩やかに結合させるために、サービス定義が完了するとインタフェースは変更されない.
Clientあるサービスを利用したい場合は、対応するインタフェースを直接呼び出せばよい.サーバがどのように実現されているかに関心を持たなくても、Clientとサーバの間で抽象化されたインタフェースに相当する.
インタフェースを定義した後、具体的な実装は状況に応じて修正することができ、Clientインタフェースの使用に影響を与えない.
AIDLはIinterfaceインタフェースクラスの自動生成を便利にし、開発者にサービスインタフェースの定義に専念させ、Iinterfaceの煩雑な細部の実現に注目する必要はなく、もちろん自分のニーズに応じて完全に自分で書くことができる.
Iinterfaceから継承されたインタフェースクラスは、AIDLツールを使用する必要はありません.AIDLはただ1つのIPCのツールで、IPCの実現の原理と関係がなくて、ただaidlの定義するインタフェースをBinderの機構に合致する以上のように生成することを手伝います
説明の3つの重要なクラス.IPCに必要なIinterfaceサブクラスの実装方法を分析します.
1)aidlファイル方式でIinterfaceのサブクラスを自動的に生成し,簡単なAIDL Demoで説明する
a.インタフェース定義サービス側が提供するインタフェースのみに注目し、AIDL規則に従ってXXXを書く.aidlファイル
aidlファイル作成規則Android Interface Definition Language(AIDL)参照
          IServiceAIDL.aidl         
// IServiceAIDL.aidl
package com.xm.androiddemo;

//aidl        java  ,           import  
import com.xm.androiddemo.IActivityAIDL;

// Declare any non-default types here with import statements

//Server     client        
//Service(Server)     Activity(Client)        aidl   

interface IServiceAIDL {

    void callService();

    //  Activity     ActivityADIL  Service ,   Service      Activity     
    void registActivityCallBack(IActivityAIDL callback);
}

b.EclipseまたはAndroid Studioは、上記aidlファイルから自動的にIServiceAIDLを生成する.JAvaファイル
Eclipseで生成されたgenディレクトリの下で、Studioは$CodePath/app/build/generated/source/aidl/
          debug/com/xm/androiddemo/IServiceAIDL.java
同様にaidlツールを自分で実行して生成することができます.aidlファイル対応javaファイル:aidl IServiceAIDL.aidl $outputPath
具体的なコードは貼らないで、自分でIServiceAIDLにいます.JAvaではIServiceAIDL,Stub,Proxyの3つのクラスが見つかり、
よく見て理解しなさい
c.Serverプロセスでサービスを提供する必要があるCodeでStubクラスのインタフェースを実現する
d.ClientプロセスでIServiceAIDLオブジェクトを作成することによってaidlファイルで定義されたサービスインタフェースを呼び出す
Demoの詳細は、次の2つの例を参照してください.
簡単なdemo学習Androidリモートサービス(AIDLの使用)
         AIDL Demo
2)開発者自身がIinterfaceサブクラスを書き,必要なインタフェースを定義し,ActivityManagerServiceを例に説明する.
IPC Binderメカニズムに関連する3つのクラスの対応する名前:
インタフェースクラス:IActivityManager.JAvaには、すべてのActivityManagerServiceが提供するサービスインタフェースとインタフェースコード(数値番号)が含まれています.
Stubクラス:ActivityManagerNative.JAvaはBinderおよびimplements IActivityManagerインタフェースクラスから継承
Proxyクラス:Activity Management Proxy.JAva ActivityManagerNativeの内部クラス、implements IActivityManagerインタフェースクラス
     
ClientとServerは以上の各種類の実現に対して:
Clientプロセス:InstrumentationクラスはActivityManagerNative.getDefault()は、AMSのためIActivityManagerインタフェースオブジェクトを取得します.
リモートプロセスに属するのでqueryLocalInterfaceはnullを返し、new Activity Management ProxyオブジェクトがAMSに転送される
プロセスのBinderオブジェクト参照、ActivityManagerProxyのstartActivityメソッドを呼び出し、startActivityの実装では主にIPC
転送する必要があるデータはParcelオブジェクトにカプセル化され、Binderのtransactメソッドを呼び出してBinder駆動プロセスに入ります.
Serverプロセス:ActivityManagerServiceは、ActivityManagerNativeから継承されます.つまり、ActivityManagerService自体がこのプロセスのBinderです.
タイプ:IActivityManager定義のサービスインタフェースを実現します.次に上のClientのstartActivityがプロセスを実行し、Binderドライバプロセスに進む
その後、下位駆動処理が完了した後、上位Activity Management NativeのonTransactメソッドをコールバックし、入力されたインタフェース番号に従って呼び出す
ActivityManagerServiceの実装のstartActivity
上記の分析を証明して、簡単にいくつかのlogを追加して、印刷の順序は上の分析と一致します
    01-01 08:08:16.112 D/ipclog ( 1817): ActivityManagerProxy transact START_ACTIVITY_TRANSACTION        01-01 08:08:16.122 D/ipclog (  596): ActivityManagerNative onTransact START_ACTIVITY_TRANSACTION     01-01 08:08:16.122 D/ipclog (  596): ActivityManagerService startActivity
上記log情報は、2つのプロセス番号1817および596596がAMSが存在するサーバプロセスであり、1817がアプリケーションプロセスであることを示す.
プロセスtransactのIPC要求を適用した後、BinderドライバはonTransactを介してサーバプロセス呼び出しサービスインタフェースの実装を呼び出す.
IPCの内容はしばらくここまで分析して、総じて言えばこの流れに対して初歩的な认识があって、深いレベルのものは后で更に学习して补充します.の
リファレンス
1.http://blog.csdn.net/linmiansheng/article/details/42438813