12

(いくつかのクライアント アプリで使用される AIDL インターフェースを備えたリモートサービスがあります。時間がかかる呼び出し用のインターフェースに非同期メソッドを追加したいのですが、ソリューションをセキュアにする必要があります。サービスと通信できます. クライアント アプリケーションはサービス アプリと同じ署名で署名されています. 現在、アプリは単にサービスにバインドし、単一のインターフェイス メソッドを呼び出してさまざまな操作を実行します.

1 つのオプションは、操作が完了したときにサービスから Intent をブロードキャストし、クライアント アプリケーションで BroadcastReceiver を使用することですが、(質問 #1 ) 私のアプリだけが Intent を受信できるようにする方法でこれを行うことはできますか? setPackage() はこれを行うようですが、Gingerbread デバイスをサポートする必要があります。これは、こちらの回答によると、そのアプローチを除外しているようです:

したがって、クライアントによって実装された、サービスが使用するコールバック インターフェイスを備えた 2 つ目の .aidl インターフェイスを追加する必要があるようです。ここでリスナーを使用する例を見てきましたが、引数として 2 番目のインターフェイス オブジェクトを渡すだけのクライアントとの違いはわかりません (この回答の IScript / IScriptResult の例で使用されているように: Service call backs to activity inアンドロイド)

質問 #2、ここでリスナーを使用することと、コールバック メソッドを使用することの利点は何ですか?

4

1 に答える 1

26

コールバック メソッド/リスナーは正しいことです。(CommonsWare が言うように、それはほとんど同じことです)。すでに aidl を使用しているため、BroadcastReceivers をいじるよりもはるかに簡単だと思います。

このようなもの:

IAsyncThing.aidl:

package com.my.thingy;

import com.my.thingy.IAsyncThingListener;

interface IAsyncThing {
  void doSomething(IAsyncThingListener listener);
}

IAsyncThingListener.aidl:

package com.my.thingy;

import com.my.thingy.IAsyncThingListener;

interface IAsyncThingListener {
  void onAsyncThingDone(int resultCodeIfYouLike);
}

サービスで署名レベルのアクセス許可を使用して、アプリのみがサービスにバインドできるようにすることができます (「サービスのアクセス許可」に関する注記を参照してください: http://developer.android.com/guide/topics/security/permissions .html )。具体的には:

  • サービスの で権限を宣言しますAndroidManifest.xml。水平であることを確認してくださいsignature
  • serviceその許可をタグに追加します
  • 他のすべてのアプリでは、使用uses-permissionして使用します。

留意すべきその他の事項がいくつかあります。

  • 呼び出し元では、 をサブクラス化する必要がありますIAsyncThingListener.Stub。呼び出し元のアプリケーション コードが既に何か他のものをサブクラス化している可能性があるため、完了通知を受け取るには追加の (おそらく内部の) クラスを使用する必要があります。これについて言及するのは、これが質問 2 の答えかもしれないからです。これは完全には理解できません。
  • サービスが呼び出し元とは異なるプロセスにある可能性がある場合は、それぞれが を使用して他のプロセスの終了通知に登録する必要がありIBinder.linkToDeathます。
于 2013-01-30T09:37:37.047 に答える