Android7.1使用Parcel和java通信读写问题

在Android7.1上实现一个Native service,通过Parcel的write或setData传递数据,存在字节对齐问题。当字节不对齐会被增加数据或者覆盖掉部分数据。
【Android7.1使用Parcel和java通信读写问题】通过实际测试规律发现,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 = %dnew_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."); } } };

经验总结,原理性掌握还需系统学习。

    推荐阅读