AIDL(Androidインターフェイス定義言語)およびプロセス間通信(IPC)

この記事では、Android IPCでのAIDLの経験について説明します。

別のプロセスで実行されているサービスを持つサンプルアプリケーションが含まれています。



記事は次のように考えるべきです:



基本的な概念




サービスは、ユーザーインターフェイスのないAndroidアプリケーションのコンポーネントであり、リソースを大量に消費する操作や長時間の操作を実行するように設計されています。



Androidサービスの種類




サービスは、アクティビティとは別のプロセスで起動できます。



利点:



短所:



エイドル


リテラル翻訳-Androidインターフェースの説明用の言語。 プロセス間の直接転送のために、JavaオブジェクトのOSプリミティブへの構成と分解を記述するために使用されます。

AIDLファイルは、次の例外を除いて、Javaの標準インターフェースに非常に似ています。



AIDLを使用して、スタブを生成するJavaコードが自動的に生成されます。



アプリケーションアーキテクチャ




私たちが開発したアプリケーションは、メモリカードと写真共有ネットワークから写真を表示できるAndroidのギャラリーです。

このアプリケーションのサービスの主な目的は、メタデータ(アルバム、写真、友人に関する情報)の取得、更新プログラム、およびそれらに関連する他のすべての監視です。 このサービスは常に関連情報を保存し、いつでもメインアクティビティに提供して表示する準備ができています。

コードの主要なセクションを以下に示し、プリミティブサービスを作成するプロセスについて説明します。

次のAIDLファイルは、サービスとアクティビティ間の通信に使用されます。



IDataSourceService.aidl-サービスインターフェイス:

packagecom.umobisoft.habr.aidlexample.common; import com.umobisoft.habr.aidlexample.common.IDataSourceServiceListener; interfaceIDataSourceService{ voidloadAlbums(in IDataSourceServiceListener listener); … }
      
      







IDataSourceServiceListener.aidl-サービスからのメッセージのリスナーのインターフェイス:

  package com.umobisoft.habr.aidlexample.common; import com.umobisoft.habr.aidlexample.common.pojo.Album; interface IDataSourceServiceListener{ oneway void albumItemLoaded(in Album a); }
      
      







データは、Parcelableインターフェイスを実装する2つのクラス-AlbumとPhotoを使用して送信されます。 これらのクラスのaidlファイルの宣言が必要です。 OSプリミティブからJavaオブジェクトに変換する場合、Creatorクラスが使用されます。

データを書き込むには、ParcelableインターフェイスのwriteToParcelメソッドを使用します。

  @Override public void writeToParcel(Parcel out, int flags) { try{ out.writeLong(id); out.writeString(name); out.writeTypedList(photos); }catch (Exception e) { Log.e(TAG, "writeToParcel", e); } }
      
      







describeContentsという補助メソッドもあります。そのタスクは、シリアル化とデシリアライゼーションに使用できるオブジェクトの特殊なケース/状態を記述することです。



  @Override public int describeContents() { // TODO Auto-generated method stub return 0; }
      
      







データを読み取る方法は、データをParcelableインターフェースに入れるのにふさわしくないことが判明しましたが、標準的な方法では、Creatorを次のものと組み合わせて使用​​します。



  private void readFromParcel(Parcel in) { try{ id = in.readLong(); name = in.readString(); photos.clear(); in.readTypedList(photos, Photo.CREATOR); }catch (Exception e) { Log.e(TAG, "readFromParcel", e); } }
      
      







アクティビティはonCreateメソッドでサービスを開始します(したがって、StartedServiceにします)。



 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView = (TextView)findViewById(R.id.album_text); Intent serviceIntent = newIntent(this, DataSourceService.class); startService(serviceIntent); connectToService(); }
      
      







ライフサイクルの同じ段階で、サービスに接続します。



  private void connectToService() { Intent intent = newIntent(this, DataSourceService.class); this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); }
      
      







サービスに接続するプロセスは非同期であり、ServiceConnectionインターフェイスの実装を実装します。 サーバーへの接続中、IDataSourceServiceListener.Stubの実装を使用して、アクティビティがメッセージリスナーとしてサービスに登録されます。



  private ServiceConnection serviceConnection = newServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG, "Service connection established"); serviceApi = IDataSourceService.Stub.asInterface(service); try { mainListener = newIDataSourceServiceListener.Stub() { @Override publicvoidalbumItemLoaded(final Album a) throwsRemoteException { mToastHandler.post(new Thread(){ publicvoid run(){ Toast.makeText(HabrahabrAIDLExampleActivity.this, a.toString(), Toast.LENGTH_LONG).show(); textView.setText(a.toString()); } }); } }; serviceApi.loadAlbums(mainListener); } catch (RemoteException e) { Log.e(TAG, "loadAlbums", e); } } @Override publicvoidonServiceDisconnected(ComponentName name) { Log.i(TAG, "Service connection closed"); serviceApi = null; connectToService(); } };
      
      







StartedServiceの実行中に、空きメモリの量が特定のしきい値まで減少すると、システムは警告なしにサービスを強制終了できます。 その後、システムはサービスを再起動する必要があります。 したがって、onServiceDisconnectedメソッドでは、サービスとの接続を再度初期化します。



レイアウトされたソースコードが、開発者がAIDLに慣れるのに役立つことを期待しています。 完全な例のあるアーカイブはこちらです。

メインアプリケーションは、 Androidマーケットで表示できます。



AndroidDevelopersの公式ドキュメント:

サービス: developer.android.com/guide/topics/fundamentals/services.html

AIDL: developer.android.com/guide/developing/tools/aidl.html



All Articles