我尝试写一个关于如何同时使用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 吗?
最佳答案
简单的回答 :是的。实际上,如果两个不同的应用程序连接到同一个服务,就会发生这种情况。
那么为什么这不起作用 ?因为您使用两个不同的接口(interface)进行通信。
详细发生了什么 :
send
Interface Descriptor
)(详情见 Stub.onTransact
) SecurityException
没有抛出
RemoteException
,因为 send()
方法还没有被调用。轻松修复 :捕获
SecurityException
。但我认为这种 非常糟糕 糟糕的风格(当您的应用程序逻辑中继异常时总是如此)。不是那么容易修复 :
为此,两个接口(interface)都需要具有相同的接口(interface)描述符(在生成的 AIDL 类中的
Stub.DESCRIPTOR
中定义)。但是,您需要自己为 IPC 实现代理/ stub (还不错)。另一个修复 :创建两个
ServiceConnection
类。一个负责 AIDL,一个负责信使。最佳修复 (IMO) :一次决定一种技术。您的解决方案感觉就像同时驾驶两辆车(独自)开车上类。
关于android - 同时使用 AIDL 和 Messenger,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8647523/