概述
在Android7.1上实现一个Native service,通过Parcel的write或setData传递数据,存在字节对齐问题。当字节不对齐会被增加数据或者覆盖掉部分数据。
通过实际测试规律发现,native传递到java,对齐方式如下:
(len-1)%4==0,如此情况,数据可被完整传递到java
(len-1)%4!=0时,最后的(len-1)%4个字节的数据被清0
native通过write传递数据,字节不对齐时,会补0.
demo:
// C++
void JNIMWListener::notify(unsigned int type, void* data, unsigned int len, void* prev)
{
HI_UNUSED(prev);
LOGD("INFO: notify enter type=0x%X (%d)", type, type);
JNIEnv* env = AndroidRuntime::getJNIEnv();
if (NULL == env)
{
return;
}
Parcel obj;
int new_len = len;
if((len-1)%4 != 0) {
new_len = len + (4 - (len-1)%4);
}
char* dataBuf = new char[new_len];
if(dataBuf == NULL) {
LOGE("no memory.");
return;
}
LOGD("len = %d
new_len = %d",len, new_len);
memcpy(dataBuf, data, len);
obj.writeInt32(len);
obj.write(data, new_len);
if (data && len > 0) /* tote extra data*/
{
jobject jParcel = createJavaParcelObject(env);
if (jParcel != NULL)
{
Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
if (NULL == nativeParcel)
{
LOGE("IparcelForJavaObject fail, nativeParcel=NULL");
goto exit;
}
nativeParcel->setData(obj.data(), obj.dataSize());
env->CallStaticVoidMethod(mClass, sFields.post_event, mObject, type, 0, 0, jParcel);
env->DeleteLocalRef(jParcel);
}
}
else /* no extra data*/
{
env->CallStaticVoidMethod(mClass, sFields.post_event, mObject, type, 0, 0, NULL);
}
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
exit:
if(dataBuf != NULL) delete[] dataBuf;
}
// java
private IMWListener mMwListener = new IMWListener() {
public void notifyMessage(int messageID, int param1, int param2, Parcel parcel)
{
switch(messageID) {
case MWMessage.HIMW_EVT_RFID_UID_TO_WIEGAND34:
if(mWeakListener.get() != null) {
if (parcel.dataAvail() <= 0) {
return ;
}
int size = parcel.readInt();
int pos = parcel.dataPosition();
Log.d(TAG, "size = : " + size);
int i = 0;
byte[] wiegand34Id = new byte[size];
for(i = 0; i < size; i++) {
wiegand34Id[i] = parcel.readByte();
// Log.d(TAG, "wiegand34Id[" + i + "]: " + Integer.toHexString(0xFF & wiegand34Id[i]));
++pos;
parcel.setDataPosition(pos);
}
parcel.recycle();
/*
String mId = null;
try {
mId = new String(wiegand34Id,"GB2312").trim();
Log.d(TAG, "wiegand34Id : " + mId);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
*/
mWeakListener.get().onWiegand34Id(wiegand34Id, size);
}
break;
default:
Log.e(TAG, "meesageID(" + messageID + ") is error.");
}
}
};
经验总结,原理性掌握还需系统学习。
最后
以上就是糟糕黑夜为你收集整理的Android7.1使用Parcel和java通信读写问题的全部内容,希望文章能够帮你解决Android7.1使用Parcel和java通信读写问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复