背景
因java的默認字節序是大端,而slp dsp需要的是小端,所以需要轉換,否則會出現各種問題。
測試用例 ByteBuffer buf = ByteBuffer.allocate(4); Log.i(TAG, "Default java endian: "+buf.order().toString()); buf.putInt(0x2); byte[] result = buf.array(); Log.i(TAG, "bytes: " + result[0]); printBytes(result); ByteBuffer buf1 = ByteBuffer.allocate(4); buf1.order(ByteOrder.LITTLE_ENDIAN); buf1.putInt(0x2); Log.i(TAG, "now java endian: "+buf1.order().toString()); result = buf1.array(); Log.i(TAG, "bytes: " + result[0]); printBytes(result);
01-01 01:15:44.734 8954 8954 I little_big_edian: Default java endian: BIG_ENDIAN
01-01 01:15:44.734 8954 8954 I little_big_edian: bytes: 0
01-01 01:15:44.734 8954 8954 I little_big_edian: 0 0 0 2
01-01 01:15:44.734 8954 8954 I little_big_edian: now java endian: LITTLE_ENDIAN
01-01 01:15:44.734 8954 8954 I little_big_edian: bytes: 2
01-01 01:15:44.734 8954 8954 I little_big_edian: 2 0 0 0
幸運的是native寫的代碼可以運行,而java層失敗,把數據打印出就可發現問題
01-01 01:52:10.271 9324 9324 E CHRE : input parameter length is: 80 bytes
01-01 01:52:10.271 9324 9324 D CHRE : Delivering message from host (size 80)
01-01 01:52:10.271 9324 9324 D CHRE : Dumping buffer of size 80 bytes
01-01 01:52:10.271 9324 9324 D CHRE : 14 00 00 00 00 00 00 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 00 00 0a 00 10 00 07 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 08 00 0e 00 0a 00 00 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 00 00 00 01 14 00 00 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 00 00 01 00 0c 00 18 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 10 00 08 00 06 00 0c 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 0c 00 00 00 00 00 02 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 05 04 00 00 0c 00 00 00 ........
01-01 01:52:10.271 9324 9324 D CHRE : 14 00 00 4d 4f 43 51 20 ...MOCQ
01-01 01:52:10.271 9324 9324 D CHRE : 04 00 00 00 00 00 00 02 ........
01-01 01:52:10.313 9324 9324 E CHRE : Failed to deliver message from host to CHRE: 104
何爲大小端
大小端的意思就是如果是佔用多個字節的數據類型,數據的低位存儲在地址的低位還是高位,如果是低位就是little endian
反之,則是big endian
frameworks/base/core/java/android/hardware/location/NanoAppBinary.java
/*
* Byte order established in context_hub.h
*/
private static final ByteOrder HEADER_ORDER = ByteOrder.LITTLE_ENDIAN;
已知byte[]到具體數據類型的轉換
源碼給出了一個例子
frameworks/base/core/java/android/hardware/location/NanoAppBinary.java
public NanoAppBinary(byte[] appBinary) {
mNanoAppBinary = appBinary;
parseBinaryHeader();
}
/*
* Byte order established in context_hub.h
*/
private static final ByteOrder HEADER_ORDER = ByteOrder.LITTLE_ENDIAN;
private void parseBinaryHeader() {
//由byte[]創建ByteBuffer,並設置大小端
ByteBuffer buf = ByteBuffer.wrap(mNanoAppBinary).order(HEADER_ORDER);
mHasValidHeader = false;
//由ByteBuffer的成員函數getInt/Long/Float等依次獲得數據,指針默認從header開始
try {
mHeaderVersion = buf.getInt();
if (mHeaderVersion != EXPECTED_HEADER_VERSION) {
Log.e(TAG, "Unexpected header version " + mHeaderVersion + " while parsing header"
+ " (expected " + EXPECTED_HEADER_VERSION + ")");
return;
}
mMagic = buf.getInt();
mNanoAppId = buf.getLong();
mNanoAppVersion = buf.getInt();
mFlags = buf.getInt();
mHwHubType = buf.getLong();
mTargetChreApiMajorVersion = buf.get();
mTargetChreApiMinorVersion = buf.get();
}
基本數據類型數據轉換爲byte[]
//根據數據類型的大小創建ByteBuffer,並設定ByteOrder
ByteBuffer buf = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
// 使用get對應的函數put賦值ByteBuffer
buf.putInt(0x02);
//得到byte[]
buf.array()//byte[]