使用の分析と作品AIDL

AIDLは、Android上の2つのプロセスのコードの間でプロセス間通信(IPC)を生成するために使用することができるインターフェイス定義言語です。

AIDLを使用

  • AIDLは、新しいファイルを作成するとの間の通信のためのプロセス・インタフェースを定義します
// IStudentManager.aidlの
パッケージcom.tellh.androidart。
// import文はここでデフォルト以外のタイプを宣言
インポート com.tellh.androidart.Student。
  インタフェースIStudentManager { リスト<学生> getStudent();    (無効addStudent における学生の学生)。}
  


注意点:

  • 彼らは同じパッケージ内であっても、基本的な型(int型、長い、文字、ブール値、など)、文字列、CharSequence引数、リスト、地図、輸入へのインポートを使用する必要があり、他のタイプ:AIDLは、パラメータの種類をサポートしていました。
  • 入力または出力端および両方あるいは、アウト、または示さinoutの使用:インタフェースは、他のAIDLサポートタイプパラメータ、他のタイプは、方向を識別しなければなりません。
  • カスタムデータ型を持っている場合は、インターフェイスをカスタマイズし、実装Parcelable AIDL宣言ファイルという新しいクラスを作成する必要があります。
// Student.aidlの
パッケージtellh.com.androidart。
parcelable学生;
パブリック クラスの学生を実装Parcelable {...}

クリックしてプロジェクトsycn、Javaクラスに対応するインタフェースが自動的にディレクトリ世代で生成されます。

  • サーバプロセス上で実行されている、サーバー側のサービスを作成します。
パブリック クラス AidlTestServiceは{サービスを拡張し
   、民間最終静的の文字列タグ= AidlTestService
  プライベート 静的な最終文字列PACKAGE_CLIENT = com.example.test.aidlclient && com.tellh.androidart
民間最終リスト<学生> mStudents = 新しい ArrayListを<>();
プライベート IBinder mBinder = 新しいIStudentManager.Stub() {
    @Override
   公共一覧<学生> getStudentは()のRemoteException {スロー
同期(mStudents){ リターンをmStudents; }
}
    @Override
  公共 無効 addStudent(学生学生)はRemoteException {スロー
  同期(mStudentsを){
    場合 mStudents.add(学生)(mStudents.contains(学生)!)。
    }   
   }
 @Override
パブリックブールonTransact(int型コード、パーセルデータ、パーセル応答、int型のフラグ)はRemoteException {スロー

    // 权限控制
    ストリングのpackageName =ヌル;
    文字列[]パッケージ= AidlTestService.this.getPackageManager()。getPackagesForUid(getCallingUid())。
    (!パッケージ= NULL && packages.length> 0){場合
      のpackageName =パッケージ[0]。
      }  
    Log.d(TAG、 "onTransact:" +のpackageName)。
    文字列[]クライアント= PACKAGE_CLIENT.split( "&&")。
   (文字列クライアント:クライアント)のための{
     IF(client.equals(のpackageName)){
       リターンsuper.onTransact(コード、データ、応答、フラグ)。}
   }
  falseを返します。
}
}。

@Override
公共ボイドのonCreate(){
  super.onCreate()。
  同期(mStudents){
    {(;; I <6 I ++のint iは1を=)のための
      学生の学生=新学生();
      student.sno = I;
      student.name = "学生#" + I;
      student.age =私は5 *;
     mStudents.add(学生)。
}}}

パブリックAidlTestService(){}
@Override
公共IBinder [OnBind]の(意図意図){mBinderを返します。}
}

登録サービス

<サービスは、Android:名= " .AidlTestService "アンドロイド:有効= " "のandroid:エクスポート= " 真の" > 
  <意図-フィルタ>
     <カテゴリは、Android:名= " android.intent.category.DEFAULT " />
     <アクションアンドロイド:名= " com.tellh.androidart.AidlTestService " />
  </インテントフィルタ>
</サービス>

クライアントとして新しいプロセスを作成し、サーバーがサービス暗黙的に開始され、コールバック関数は、によって結合されたIStudentManager.Stub.asInterface(binder)通信インタフェースを取得するために、プロキシオブジェクト。

パブリック クラス AidlClientActivityは拡張 ActionBarActivity { 
  プライベート文字列のタグ=「AidlClientを」。
  プライベート 静的な 最終文字列ACTION_BIND_SERVICE =「com.tellh.androidart.AidlTestService」。
  プライベート IStudentManager mStudentManager。
    // バインダー连接断裂(死亡)代理
  プライベートIBinder.DeathRecipient mDeathRecipient =新しいIBinder.DeathRecipient(){
    @Override
    ます。public void binderDied(){
       場合(mStudentManager == nullの)リターン。
        mStudentManager.asBinder()unlinkToDeath(mDeathRecipient、0)。
        mStudentManager = NULL;
        bindService(); }
   }。

  プライベートServiceConnection mServiceConn =新しいServiceConnection(){
    @Override
    ます。public void onServiceConnected(コンポーネント名名、IBinderサービス){
      mStudentManager = IStudentManager.Stub.asInterface(サービス);
      試す{service.linkToDeath(mDeathRecipient、0); }
      キャッチ(RemoteExceptionを電子){e.printStackTrace(); }
    }
    @Override
    公共ボイドonServiceDisconnected(コンポーネント名名){mStudentManager = NULL; }
}。

@Overrideは、
ボイドのonCreate(バンドルsavedInstanceState)を保護{
    super.onCreate(savedInstanceState)。
    setContentView(R.layout.activity_aidl_client)。
    bindService(); }
プライベートボイドbindService(){
  テントの意図=新しいテント(ACTION_BIND_SERVICE)。
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。
  intent.setPackage( "com.tellh.androidart");
   bindService(意図、mServiceConn、BIND_AUTO_CREATE)。
}
@Overrideは
ボイドonDestroy(){保護
  super.onDestroyを();
  (!mStudentManager = null)のunbindService(mServiceConn)であれば、
}
公共ボイドonClickGetStudent(ビュービュー){
  IF(mStudentManager == NULL)のリターン;
  試す{Log.d(タグ、mStudentManager.getStudent()のtoString())。}
  キャッチ(RemoteExceptionを電子){e.printStackTrace(); }}
公共ボイドonClickAddStudent(ビュービュー){
  IF(mStudentManager == NULL)のリターン;
  {学生学生=新しい学生を()してみてください。
  student.sno = 7。
  student.age = 10。
  student.name = "TellH"。
  student.sex = Student.SEX_MALE。
  mStudentManager.addStudent(学生)。
  Log.d(タグ、mStudentManager.getStudent()のtoString())。
}
キャッチ(RemoteExceptionを電子){e.printStackTrace(); }}}

登録活動、新しいプロセスで実行

< 活動
            アンドロイド:名 = "AidlClientActivity。" 
            アンドロイド:プロセス = ":クライアント" />

アプリケーション間の通信は、クライアント・アプリケーションは、すべての上にAIDLファイルサーバのコピーに必要がある場合、および、同じパッケージ名を確保するために

AIDL作品

分析インタフェースコードを自動的に生成するJava:

pubblic インタフェース IStudentManagerは延び android.os.IInterface { 

パブリック 静的 抽象 クラススタブが延び android.os.Binder 実装 tellh.com.androidart.IStudentManager {...}
公共 java.util.Listに<tellh.com.androidart.Student> getStudentを()スロー android.os.RemoteExceptionは、
公共 のボイド addStudent(tellh.com.androidart.Student学生)がスロー android.os.RemoteExceptionを。

このインタフェースクラスには、バインダーインタフェース内のすべての送信がメソッドはIInterfaceを継承しなければならない、メソッドはIInterfaceを継承します。また、それは我々がAIDLファイル内の2つのメソッドを定義するだけでなく、自動的にスタブの名前の静的クラスを生成保持します。スタブこれは、[OnBind]の復帰は、クライアントへの復帰、IStudentManager.Stub.asInterface(バインダー)を介してクライアントへの手段として、バインダーから実装、このインタフェースとクラスの継承は、サービスのサービス側でインスタンス化されることが抽象クラスでありますこのインターフェイスプロキシオブジェクトクラス。
スタブ抽象クラスのメンバーと属性:
    DESRIPTORは
一意に、一般的にバインダーの現在の完全なクラス名で示され、バインダーを識別します。
    パブリック静的IStudentManager asInterface(IBinder OBJ)

と同じプロセス内のクライアントとサーバは、その後、スタブオブジェクト自体のサービス側に直接戻ると、そうでない場合はStub.Proxyプロキシオブジェクト。

    パブリックブールonTransact(INTコード、android.os.Parcelのデータ、android.os.Parcel応答、INTフラグ)

サーバスレッドプールバインダー上で実行される、ターゲットメソッドを決定することにより、サーバコードは、クライアントによって要求されていますどのような所望の目標パラメータデータメソッドから除去し、次にターゲット、メソッドの戻り値と目標書き込み応答を行っています。このメソッドがfalseを返した場合、クライアントの要求は失敗へ戻ります。したがって、我々は、検証機関を行うには、この機能を使用することができます。

    #AddStudentプロキシ

プロキシは、プロキシクラス、またはデコレータクラスです。

@Override 公共 java.util.Listに<tellh.com.androidart.Student> getStudent()スロー android.os.RemoteExceptionを{ 
   android.os.Parcel _data = android.os.Parcel.obtain()。
android.os.Parcel _reply = android.os.Parcel.obtain()。
java.util.Listに<tellh.com.androidart.Student> _result。

試す {
_data.writeInterfaceToken(DESCRIPTOR)。
mRemote.transact(Stub.TRANSACTION_getStudent、_data、_reply、0);
_reply.readException()。
_result = _reply.createTypedArrayList(tellh.com.androidart.Student.CREATOR)。}
最後に {
    _reply.recycle()。
    _data.recycle()。
}
リターン_結果; }


現在のスレッドを中断しながら各プロキシメソッドが同じルーチンであり、mRemote.transactオブジェクトメソッドに渡された方法、パラメータおよび戻り値を識別し、要求はリモート呼び出しを開始するために、次にスタブ#onTransactサーバが呼び出されます。onTransactがtrueを返した場合、呼び出しは、削除対象の回答、呼び出し元にクライアントが戻るからの戻り値を成功します。

 

 

要約

使用AIDLの高レベルの概要を、サーバ側のサービスが存在し、バインダーオブジェクト設けられた特定のクライアント・プロセスの(bindService)に結合します。静的メソッドAIDL asInterfaceバインダーオブジェクトを介してクライアント・インタフェースを使用すると、リモート呼び出し要求を開始することができ、プロキシを介してAIDLプロキシオブジェクトインタフェースに変換されます。

より詳細については、リモート・プロシージャ・コールは、次の図にまとめることができます。


----------------
免責事項:この記事は元の記事CSDNブロガー「TellH」で、未定義の著作権契約以下、オリジナルのソースリンクと、この文を添付してください、再現。
オリジナルリンクします。https://blog.csdn.net/tellh/article/details/55100167

 

おすすめ

転載: www.cnblogs.com/yz123/p/12011108.html