AIDL和Messenger同时出现

时间:2011-12-27 17:36:40

标签: android aidl messenger

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

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

1 个答案:

答案 0 :(得分:4)

  

我可以多次拨打onBinder吗?

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

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

详细信息

  1. 您连接到服务(AIDL)
  2. 您尝试通过信使send发送消息
  3. Android通过AIDL将此消息发送给服务
  4. 要做的第一件事是,给定的接口匹配(通过比较Interface Descriptor)(详情请见Stub.onTransact
  5. Android注意到这些界面不匹配并抛出SecurityException
  6. 没有抛出RemoteException,因为尚未调用send()方法。

    轻松修复:抓住SecurityException。但我会考虑这种极端错误的样式(就像你的应用程序逻辑在异常时中继一样)。

    不太容易解决: 为此,两个接口都需要具有相同的接口描述符(在生成的AIDL类中的Stub.DESCRIPTOR中定义)。但是你需要自己实现IPC的代理/存根(不是那么糟糕)。

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

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