AIDL and Messenger at the same time

I am trying to write a demo on how to use AIDL and Messenger at the same time, but I have an error and I don’t know the reason.

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(); } } 

And the stack trace:

 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) 

Without these lines, the code works:

 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(); } 

It works without AIDL and runs AIDL "one". Can I call onBinder more than once?

+4
source share
1 answer

Is it possible to call onBinder more than once?

The simple answer is yes. In fact, this happens if two different applications connect to the same service.

So why does this work not work ? Because you use two different interfaces for communication.

What happens in detail :

  • You are connecting to a service (AIDL)
  • You are trying to send message
  • Android sends this message to the AIDL service
  • First of all, these interfaces need to be consistent (comparing the Interface Descriptor ) (see Stub.onTransact below for more details)
  • Android notes that these interfaces do not match and throws a SecurityException

There is no RemoteException because the send() method is not yet called.

Easy fix : catch a SecurityException . But I would consider this extreme bad style (as always when your application logic decides on exceptions).

Not so easy to fix : For this to work, both interfaces must have the same interface descriptor (defined in Stub.DESCRIPTOR in the generated AIDL class). However, you will need to implement Proxy / Stub for IPC yourself (not so bad).

Another fix . Create two ServiceConnection classes. One responsible for the AIDL, one for the messenger.

Best Fix (IMO) . Solve one technique at a time. Your decision is like driving to work (alone) with two cars at the same time.

+4
source

Source: https://habr.com/ru/post/1388176/


All Articles