ContextHub: java 字節和數據類型的轉換

背景

因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[]

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章