前提:
媒体服务提供一个SDK给N多个应用集成,某个应用(A)来一个新需求,需要在service端传输数据MediaInfo里添加一个字段F(String),于是给A一个新版本SDK
问题:
A收到F有时候有值有时候为null
分析:
service端日志可以看出传输给各个client前F是有值的,而传输过程中发现F变为null
第一反应就是MediaInfo对象在哪被修改了,然而在Android Studio 里搜索下write地方只有一处,显然不是service内部修改值
进一步加日志,定位到某次binder传输数据给某个client前数据正常,传输后就变null,说明是跨进程传导致数据异常
接着分析传输过程中哪里导致数据被修改,调试进入aidl生成的java类中对应的回调方法,发现有回写数据
@Override public void onMediaInfoChanged(int mediaType, xxx.MediaInfo mediaInfo) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(mediaType);
if ((mediaInfo!=null)) {
_data.writeInt(1);
mediaInfo.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
boolean _status = mRemote.transact(Stub.TRANSACTION_onMediaInfoChanged, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
getDefaultImpl().onMediaInfoChanged(mediaType, mediaInfo);
return;
}
_reply.readException();
if (0 != _reply.readInt()) {
mediaInfo.readFromParcel(_reply); // 回写数据
}
finally {
_reply.recycle();
_data.recycle();
}
}
看到这里我就想,我传输个数据为啥要回写,而且此处有个判断条件,那么是否可以通过影响这个条件来控制回写数据,而reply对象传进了transct方法
从接口说明上看reply似乎可控,于是找到aidl文件
interface IMediaInfoCallback {
void onMediaInfoChanged(int mediaType,inout MediaInfo mediaInfo);
...
}
inout, 改为in,数据不会回写(经确认此处完全不需要inout)