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

在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.");
			}
		}
	};

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

发布了93 篇原创文章 · 获赞 12 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/mcsbary/article/details/103459368