我这几天一直遇到 IPC 问题。但在 pskink 的慈善帮助下,我学到了很多东西。
我讨厌 AIDL。我讨厌这个词。为什么这个奇怪的新术语实际上只是一些实现 onTransact 并调用事务的 java 类。没有必要,而且比自己做更难实现!
所以调用AIDL接口:
打印.aidl
interface Print
{
void print(String s);
}
原谅我的助手代码。然而,AIDL 编译器将其编译为 java 文件。
打印.java
// note that AIDL takes care to use fully qualified names
public interface Print
{
void print(String s);
// This is used for local process calls
public abstract static class Stub extends Binder
implements Print
{
private Stub()
{
attachInterface(this);
}
public static Print asInterface(IBinder binder)
{
return binder == null ? null :
binder instanceof Print.Stub ? new Print.Stub() :
/* else */ new Print.Stub.Proxy(binder);
}
@Override public IBinder asBinder { return this; }
@Override public boolean onTransact(int event,Parcel out,Parcel reply,int flags)
{
switch(event)
{
case TRANSACTION_print: // print data.readString();
}
}
// This is used for IPC
private static class Proxy implements Print
{
IBinder binder;
@Override public void print(String s)
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeString(s);
binder.transact(TRANSACTION_print,data,reply,0);
reply.readException();
}
}
}
}
这几乎是 AIDL 生成的代码,从不向您展示。我不知道为什么它与 JIDL 或 PIEL 或 TBHJ 不同。但是我们不需要 AIDL 工具,上面的所有代码都可以简化!
process1/Print.java
public class Print extends Binder
{
public void print(String s) { // print string }
@Override public boolean onTransact(int event,Parcel out,Parcel reply,int flags)
{
switch(event)
{
case TRANSACTION_print: // print data.readString();
}
}
}
处理2/打印
public class Print
{
public void print(String s)
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeString(s);
binder.transact(TRANSACTION_print,data,reply,0);
reply.readException();
}
}
正如您所看到的那样简单。唯一遗漏的是使用本地函数与进程代理的决定。这很容易实现。
请注意,Binders 不适用于 IPC 句号...它们仅适用于绑定服务到客户端的通信。尝试在两个活动之间进行交易似乎有效。正如 pskink 指出的那样。
要在两个活动之间进行通信,您可以使用 Messenger api。据说 Messenger 只是使用活页夹,但我认为这是半真半假。正如我所说,使用活页夹在两个活动之间进行通信失败了!顺便说一句,Binder 是一个内核驱动程序。所以我猜 Messenger 使用的 binder 是一个特殊的内核 binder 驱动程序!
另一种通信方式是通过 ParcelFileDescriptor.createPipe()!!!!嗯,宝贝。 Android 支持管道。问题是,通过意图对它们进行编组是完全失败的,并且应用程序会严重崩溃。管道再次,似乎只用于服务到活动的通信。
最后。不能使用活页夹聊天真是太荒谬了。两个活动在不同的进程中。无法将可打包描述符放入意图中。你必须遵循设定在你身上的教义。更糟糕的是,糟糕的文档。