我尝试写一个关于如何同时使用AIDL和Messenger的demo,但是出现错误,不知道原因。

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 吗?

最佳答案



简单的回答 :是的。实际上,如果两个不同的应用程序连接到同一个服务,就会发生这种情况。

那么为什么这不起作用 ?因为您使用两个不同的接口(interface)进行通信。

详细发生了什么 :

  • 您连接到服务 (AIDL)
  • 您尝试通过信使
  • 对消息进行 send
  • Android 通过 AIDL 将此消息发送到服务
  • 首先要做的是,给定的接口(interface)匹配(通过比较 Interface Descriptor )(详情见 Stub.onTransact)
  • Android 注意到这些接口(interface)不匹配并抛出 SecurityException

  • 没有抛出 RemoteException,因为 send() 方法还没有被调用。

    轻松修复 :捕获 SecurityException 。但我认为这种 非常糟糕 糟糕的风格(当您的应用程序逻辑中继异常时总是如此)。

    不是那么容易修复 :
    为此,两个接口(interface)都需要具有相同的接口(interface)描述符(在生成的 AIDL 类中的 Stub.DESCRIPTOR 中定义)。但是,您需要自己为 IPC 实现代理/ stub (还不错)。

    另一个修复 :创建两个 ServiceConnection 类。一个负责 AIDL,一个负责信使。

    最佳修复 (IMO) :一次决定一种技术。您的解决方案感觉就像同时驾驶两辆车(独自)开车上类。

    关于android - 同时使用 AIDL 和 Messenger,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8647523/

    10-10 10:00