3

AIDL を実装しようとしていますが、その仕組みがわかりません。これは、メソッド呼び出しの進行状況を意味します。

AIDL を介してサービスからアクティビティにオブジェクトを取得する方法がわかりません。ガイダンスとしてGoogleドキュメントを使用していますが、混乱しています.Thanks.

アップデート:

Service Connection には、mCallback が IRemoteServiceCallback であるこれらの行があります。

 public void onServiceConnected(ComponentName name, IBinder service) {
            mRemoteInterface = IRemoteInterface.Stub.asInterface(service);
            Log.v(TAG, "Interface bound.");
            try{
                mRemoteInterface.registerCallback(mCallback);
            }catch(RemoteException e){

            }
            Toast.makeText(MainActivity.this, "Remote Service Connected",
                    Toast.LENGTH_SHORT).show();
        }

これが registerCallback で、mCallbacks は

final RemoteCallbackList <IRemoteServiceCallback> mCallbacks

    = new RemoteCallbackList <IRemoteServiceCallback> ();

.....

public void registerCallback(IRemoteServiceCallback callback)
                throws RemoteException {
            if(callback != null){
                mCallbacks.register(callback);
            }

        }

IRemoteServiceCallback(mCallback) が持つ唯一のメソッドは次のとおりです。

public void valueChanged(int value) {
        mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
    }

私もハンドラーを持っていますが、それをどうするかよくわかりません:

 private Handler mHandler = new Handler() {
    @Override public void handleMessage(Message msg) {
        switch (msg.what) {
            case BUMP_MSG:
                Log.d(TAG, "Received from service: " + msg.arg1);
                break;
            default:
                super.handleMessage(msg);
        }
    }

};

更新 2:

AIDL ステップ -私が理解していることから-。

  1. MainActivity から bindService(service,connection,flags) を呼び出します

  2. bindService を呼び出して接続が確立されると、onServiceConnected が自動的に呼び出されます。その中で、IBinder を取得し、registerCallback を呼び出して IRemoteServiceCallback[ WHERE DOES THIS CALLBACK COME FROM?? ] を RemoteCallbackList に追加して、後でアクセスできるようにします

ここで、サービスに 1 つ、アクティビティに 1 つの、2 つの mHandler があることに気付きました。[これらはいつ呼び出され、使用上の違いは何ですか]

これで、RemoteCallbackList には必要なコールバックが含まれており、アクティビティ クラスの mHandler で必要なオブジェクトを最終的に取得できることがわかります。

4

1 に答える 1

12

Android のクロスアプリケーション サービスは、カーネル レベルの IPC システムである Binder に基づいています (これがIBinderクラス名の由来です)。リモート サービス (つまり、アプリケーションの外部のサービス) にバインドすると、オブジェクトを返すことができます。ただし、実際の型 (メソッド、フィールドなど) がわからないため、使用可能な型にキャストすることはできません。

ここで AIDL の出番です。AIDL は言語にとらわれずにインターフェースを指定する方法であり、メソッドとそのパラメーターのコレクションです (一見 Java のように見えますが、そうではありません)。クライアントとサーバーの両方が同じ .aidl ファイルを使用する場合、生成された Java インターフェイスを介してオブジェクトにバインドできます - IRemoteService.Stub.asInterface(obj). サービス側では、同じインターフェースを何らかの言語 (フレームワーク内の一部のサービスは C++ で記述) で実装するだけでよく、残りは IPC メカニズムが処理します。

とはいえ、サービスをエクスポートして外部アプリケーションで使用できるようにする場合を除き、AIDL を使用する必要はありません。そうでない場合は、アプリケーションに IBinder を実装し、受け取ったオブジェクトをonServiceConnected直接キャストします。これは、その型がわかっているためです。

于 2013-07-26T16:31:42.630 に答える