2011-12-27 26 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