2011-12-27 62 views
4

我尝试写一个演示关于如何使用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吗?

回答

4

我可以多次调用onBinder吗?

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

那么,为什么不工作?因为你使用两个不同的接口进行通信。

详细会发生什么:

  1. 您连接到服务(AIDL)
  2. 您可以通过信使
  3. Android的尝试send消息通过AIDL
  4. 将这个消息发送给服务
  5. 首先要做的是,给定的接口确实匹配(通过比较Interface Descriptor)(详情请参阅Stub.onTransact
  6. 的Android注意到这些接口不匹配,并抛出一个SecurityException

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

简易修复:赶上SecurityException。但我认为这是极端糟糕的样式(通常是当你的应用程序逻辑在异常中继时)。

没那么容易修复: 对于这项工作,这两个接口都需要有相同的接口描述符(在你产生AIDL类Stub.DESCRIPTOR定义)。但是你需要自己实现IPC的代理/存根(不是那么糟糕)。

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

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

+0

现在我明白了,但你是什么意思:另一个修复:创建到ServiceConnection类。一个负责AIDL的人,一个负责信使。 – 2011-12-27 19:16:37

+0

我喜欢同时驾驶两辆车:D。你应该试试。 – 2011-12-27 19:19:53

+0

@Forro:这是一个拼写错误,意思是'两'。 – Fge 2011-12-27 19:59:43