4

AIDLとメッセンジャーを同時に使用する方法のデモを書こうとしていますが、エラーが発生し、理由がわかりません。

MessengerDEMOActivity.java

public class MessengerDEMOActivity extends Activity {
    /** Called when the activity is first created. */

    private MessengerDEMOServiceConnection MDSconnection = null;
    private Messenger mMessenger = null;

    class IncomingHandler extends Handler {
            public void handleMessage(Message msg) {
            Bundle b = msg.getData();
            System.out.println("MESSENGER! " + b.getString("MESSENGER"));
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mMessenger = new Messenger(new IncomingHandler());

        MDSconnection = new MessengerDEMOServiceConnection(mMessenger);
        Intent intent = new Intent();
        intent.putExtra("ID", "AIDL");
        intent.setClassName("messenger.demo", messenger.demo.MessengerDEMOService.class.getName());
        bindService(intent, MDSconnection, Context.BIND_AUTO_CREATE);

    }
}

MessengerDEMOServiceConnection.java

public class MessengerDEMOServiceConnection implements ServiceConnection {

    private IMessengerDEMOService service = null;
    private Messenger mMessenger = null;

    public MessengerDEMOServiceConnection(Messenger mMessenger) {
        super();
        System.out.println("MessengerDEMOServiceConnection SocketServiceConnection()");
        this.mMessenger = mMessenger;
    }

    public void onServiceConnected(ComponentName name, IBinder boundService) {
        System.out.println("MessengerDEMOServiceConnection onServiceConnected()");
        service = IMessengerDEMOService.Stub.asInterface((IBinder) boundService);

        Messenger mService = new Messenger(boundService);

        Message msg = Message.obtain(null, 5);
        msg.replyTo = mMessenger;
        try {
            mService.send(msg); // line 31
        } catch (RemoteException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        try {
            service.foo();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void onServiceDisconnected(ComponentName name) {
        System.out.println("MessengerDEMOServiceConnection onServiceDisconnected()");
        service = null;
    }
}

MessengerDEMOService.java

public class MessengerDEMOService extends Service {

    private Messenger mMessenger = null;

    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            System.out.println("MessengerDEMOService IncomingHandler");
            Messenger activityMessenger = msg.replyTo;
            Message m = new Message();
            Bundle b = new Bundle();
            b.putString("MESSENGER", "blablabla");
            m.setData(b);
            try {
                activityMessenger.send(m);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void onCreate() {
        System.out.println("MessengerDEMOService onCreate");
        mMessenger = new Messenger(new IncomingHandler());
    }

    public IBinder onBind(Intent intent) {

        System.out.println("MessengerDEMOService onBind()");

        if (intent.getExtras().getString("ID").equals("AIDL") == true) {
            System.out.println("MessengerDEMOService onBind() AIDL");
            return new IMessengerDEMOService.Stub() {
                public void foo() {
                    System.out.println("MessengerDEMOService onBind() foo()");
                }
            };
        }

        System.out.println("MessengerDEMOService onBind() MESSENGER");
        return mMessenger.getBinder();
    }
}

そしてスタックトレース:

12-27 16:42:29.412: INFO/System.out(832): MessengerDEMOServiceConnection SocketServiceConnection()
12-27 16:42:29.442: INFO/System.out(832): MessengerDEMOService onCreate
12-27 16:42:29.452: INFO/System.out(832): MessengerDEMOService onBind()
12-27 16:42:29.452: INFO/System.out(832): MessengerDEMOService onBind() AIDL
12-27 16:42:29.542: INFO/System.out(832): MessengerDEMOServiceConnection onServiceConnected()
12-27 16:42:29.572: WARN/Parcel(832): **** enforceInterface() expected 'messenger.demo.IMessengerDEMOService' but read 'android.os.IMessenger'
12-27 16:42:29.572: DEBUG/AndroidRuntime(832): Shutting down VM
12-27 16:42:29.572: WARN/dalvikvm(832): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-27 16:42:29.592: ERROR/AndroidRuntime(832): FATAL EXCEPTION: main
12-27 16:42:29.592: ERROR/AndroidRuntime(832): java.lang.SecurityException: Binder invocation to an incorrect interface
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Parcel.enforceInterface(Native Method)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at messenger.demo.IMessengerDEMOService$Stub.onTransact(IMessengerDEMOService.java:49)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Binder.transact(Binder.java:249)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.IMessenger$Stub$Proxy.send(IMessenger.java:89)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Messenger.send(Messenger.java:50)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at messenger.demo.MessengerDEMOServiceConnection.onServiceConnected(MessengerDEMOServiceConnection.java:31)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.app.ActivityThread$PackageInfo$ServiceDispatcher.doConnected(ActivityThread.java:1247)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.app.ActivityThread$PackageInfo$ServiceDispatcher$RunConnection.run(ActivityThread.java:1264)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Handler.handleCallback(Handler.java:587)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Handler.dispatchMessage(Handler.java:92)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.os.Looper.loop(Looper.java:123)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at android.app.ActivityThread.main(ActivityThread.java:4627)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at java.lang.reflect.Method.invokeNative(Native Method)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at java.lang.reflect.Method.invoke(Method.java:521)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-27 16:42:29.592: ERROR/AndroidRuntime(832):     at dalvik.system.NativeStart.main(Native Method)

これらの行がないと、コードは機能します。

Message msg = Message.obtain(null, 5);
            msg.replyTo = mMessenger;
            try {
                mService.send(msg); // line 31
            } catch (RemoteException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

AIDLなしで動作し、AIDLを「単独で」動作します。onBinderを複数回呼び出すことはできますか?

4

1 に答える 1

4

onBinderを複数回呼び出すことはできますか?

簡単な答え:はい。実際、これは2つの異なるアプリケーションが同じサービスに接続する場合に発生します。

では、なぜこれが機能しないのですか?通信に2つの異なるインターフェースを使用しているためです。

詳細に何が起こるか

  1. サービスに接続します(AIDL)
  2. あなたsendはメッセンジャーによるメッセージを試みます
  3. AndroidはこのメッセージをAIDLによってサービスに送信します
  4. 最初に行うことは、指定されたインターフェイスが(を比較することによって)一致するInterface Descriptorことです(詳細についてはお会いしましょうStub.onTransact
  5. Androidは、これらのインターフェースが一致しないことに気づき、SecurityException

メソッドがまだ呼び出されていないRemoteExceptionため、スローされません。send()

簡単な修正:キャッチSecurityException。しかし、私はこれを非常に悪いスタイルだと思います(いつものように、アプリケーションロジックが例外を中継するときです)。

それほど簡単な修正ではありません:これを機能させるには、両方のインターフェイスが同じインターフェイス記述子(Stub.DESCRIPTOR生成されたAIDLクラスで定義されている)である必要があります。ただし、IPCのプロキシ/スタブは自分で実装する必要があります(それほど悪くはありません)。

別の修正:2つのServiceConnectionクラスを作成します。1つはAIDLを担当し、もう1つはメッセンジャーを担当します。

ベストフィックス(IMO):一度に1つのテクニックを決定します。あなたの解決策は、同時に2台の車で(一人で)仕事をするように運転しているように感じます。

于 2011-12-27T18:59:16.653 に答える