我尝试编写一个关于如何同时使用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吗?
答案 0 :(得分:4)
我可以多次拨打onBinder吗?
简单回答:是的。实际上,如果两个不同的应用程序连接到同一服务,就会发生这种情况。
那么为什么这不起作用?因为您使用两个不同的接口进行通信。
详细信息:
send
发送消息Interface Descriptor
)(详情请见Stub.onTransact
)SecurityException
没有抛出RemoteException
,因为尚未调用send()
方法。
轻松修复:抓住SecurityException
。但我会考虑这种极端错误的样式(就像你的应用程序逻辑在异常时中继一样)。
不太容易解决:
为此,两个接口都需要具有相同的接口描述符(在生成的AIDL类中的Stub.DESCRIPTOR
中定义)。但是你需要自己实现IPC的代理/存根(不是那么糟糕)。
另一个修复:创建两个ServiceConnection
类。一个负责AIDL,一个负责信使。
最佳修复(IMO):一次确定一种技术。您的解决方案感觉就像开车(单独)同时驾驶两辆车一样。