AIDL 和 Messenger 同时使用
我尝试写一个关于如何同时使用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 吗?
I try to write a demo about how to use the AIDL and the 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 is working:
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 the AIDL and works the AIDL "alone". Can I call the onBinder more than one time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
简单答案:是的。实际上,如果两个不同的应用程序连接到同一服务,就会发生这种情况。
那么为什么这不起作用?因为您使用两个不同的接口进行通信。
详细情况:
发送
消息接口描述符
)(有关详细信息,请参阅Stub.onTransact
)SecurityException
有没有抛出
RemoteException
,因为尚未调用send()
方法。简单修复:捕获
SecurityException
。但我认为这种极其糟糕的风格(当你的应用程序逻辑中继异常时总是如此)。修复起来并不容易:
为此,两个接口需要具有相同的接口描述符(在生成的 AIDL 类中的
Stub.DESCRIPTOR
中定义)。但是,您需要自己实现 IPC 的代理/存根(还不错)。另一个修复:创建两个
ServiceConnection
类。一名负责 AIDL,一名负责信使。最佳解决方案(IMO):一次决定一种技术。您的解决方案感觉就像同时驾驶两辆车(独自)去上班。
Simple answer: yes. Actually this does happen if two different applications connect to the same service.
So why doesn't this work? Because you're using two different interfaces for communication.
What happens in detail:
send
a message by the messengerInterface Descriptor
) (See youStub.onTransact
for details)SecurityException
There is no
RemoteException
thrown because thesend()
method isn't invoked yet.Easy fix: catch the
SecurityException
. But I'd consider this extremly bad style (as always it is when your application logic relays on exceptions).Not so easy fix:
For this to work, both interfaces would need to have to same interface descriptor (defined in
Stub.DESCRIPTOR
in your generated AIDL class). However you'd need to implement the Proxy/Stub for IPC by yourself (not that bad).Another fix: Create two
ServiceConnection
classes. One responsible for AIDL, one for the messenger.Best fix (IMO): Decide for one technique at a time. Your solution feels like driving to work (alone) with two cars at the same time.