Android JNI 由C/C++本地代碼向Java層傳遞數據


最近做的Android項目需要調用C代碼,進行串口通信及與硬件設備通信,因此要用到JNI,其中本地代碼需要向Java層返回三個參數,分別為

參數一:int型;

參數二: 通信指令,本地代碼中為unsigned char[]型,返回unsigned char[]、int[]都可以,能直接將數據轉換為16進制字符串最好(Android界面上要顯示的就是數組每一位的16進制值);

參數三:同參數二。

具體的實現方式有兩種。

第一種是C代碼獲取Java屬性參數,本地修改參數值。

第二種是將三個參數定義為對象,作為函數返回值返回給Java層。

 

第二種方法的實現,這里定義了一個對象數組,滿足參數二、三的要求,即返回int型數組,而對於參數一來說有些浪費。

Java 代碼:

package com.fansen.hellojni;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {

    @SuppressLint("DefaultLocale")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView  tv = new TextView(this);
        tv.setText( "Hello World!" );
        
        DiskInfo[] infos = stringFromJNI();
        for (int i = 0; i < infos.length; i++) {

        Log.i("TAG", "infos[" + i + "].data: " + infos[i].data);
        Log.i("TAG", "infos[" + i + "].value: " + infos[i].value);
        Log.i("TAG", "infos[" + i + "].number: " + infos[i].number);

        }

        setContentView(tv);
    }
    
    public native DiskInfo[]  stringFromJNI();

    static {
        System.loadLibrary("hello-jni");
    }

}

class DiskInfo{
    public int data;
    public int value;    
    public int number;    
}

 

C代碼:

#include <string.h>
#include <jni.h>

typedef struct{
    int data;
    int value;
    int number;
} DiskInfo;

jobjectArray  Java_com_fansen_hellojni_MainActivity_stringFromJNI( JNIEnv* env, jobject thiz )
{
    jclass clsDiskInfo = (*env)->FindClass(env, "com/fansen/hellojni/DiskInfo");
    jobjectArray infos = (*env)->NewObjectArray(env, 10, clsDiskInfo, NULL);

    jfieldID dataID = (*env)->GetFieldID(env, clsDiskInfo, "data", "I");
    jfieldID valueID = (*env)->GetFieldID(env, clsDiskInfo, "value", "I");
    jfieldID numberID = (*env)->GetFieldID(env, clsDiskInfo, "number", "I");
    jmethodID consID = (*env)->GetMethodID(env, clsDiskInfo, "<init>", "()V");

    unsigned char send[10] = {0xFF,0x1F,0x07,0x08,0x00,0x00,0x01,0x02};

    int sendcopy[10] = {0};
    int j;
    for(j = 0; j <= 8; j++){
        sendcopy[j] = send[j];  //模擬C代碼值變化
    }

    int i;
    jobject obj;
    for(i = 0; i < 10; i++){
        obj = (*env)->NewObject(env, clsDiskInfo, consID);
        (*env)->SetIntField(env, obj, dataID, (jint)i);
        (*env)->SetIntField(env, obj, valueID, (jint)sendcopy[i]);
        (*env)->SetIntField(env, obj, numberID, (jint)sendcopy[i]); 
     (
*env)->SetObjectArrayElement(env, infos, i, obj);
  }
  return infos;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM