JNI系列——PassData

1.在工程目录下创建xxx.jni包并在该包下创建JNI类

2.在JNI类中声明所有的本地方法,并加载库

3.在MainActivity类中实例化JNI对象,并调用其方法

4.通过Javah生成的方法名在对应C文件中进行实现

5.在jni目录下添加Android.mk和Application.mk文件

Demo:

JNI.java:

public class JNI
{
    static {        
        System.loadLibrary("pass_data");
    }
    public native int add(int x, int y);
    public native String string(String str);
    public native int [] intArrayElements(int[] array);
}

MainActivity.java:

public class MainActivity extends Activity implements OnClickListener
{
    Button bt_int = null;
    Button bt_string = null;
    Button bt_array = null;
    public JNI jni = null;
    Context mContext = null;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        jni = new JNI();
        bt_int = (Button) findViewById(R.id.bt_int);
        bt_string = (Button) findViewById(R.id.bt_string);
        bt_array = (Button) findViewById(R.id.bt_array);
        bt_int.setOnClickListener(this);
        bt_string.setOnClickListener(this);
        bt_array.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
        case R.id.bt_int:
            Toast.makeText(mContext, jni.add(4, 8) + "", Toast.LENGTH_SHORT).show();
            break;
        case R.id.bt_string:
            Toast.makeText(mContext, jni.string("abcdefg"), Toast.LENGTH_SHORT).show();
            break;
        case R.id.bt_array:
            int [] array = new int[]{1, 2, 3, 4, 5};
            jni.intArrayElements(array);
            for (int i : array)
            {
                Log.d("test", i + "");
            }
            break;
        default:
            break;
        }
    }
}

pass_data.c

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
/*
 * Class:     com_rocky_passdata_jni_JNI
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_rocky_passdata_jni_JNI_add
  (JNIEnv *env, jobject clazz, jint x, jint y)
{
    return x + y;
}
/**
 * 把一个jstring转换成一个c语言的char* 类型.
 */
char* _JString2CStr(JNIEnv* env, jstring jstr) {
     char* rtn = NULL;
     jclass clsstring = (*env)->FindClass(env, "java/lang/String");
     jstring strencode = (*env)->NewStringUTF(env,"GB2312");
     jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
     jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); // String .getByte("GB2312");
     jsize alen = (*env)->GetArrayLength(env, barr);
     jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
     if(alen > 0) {
        rtn = (char*)malloc(alen+1); //"\0"
        memcpy(rtn, ba, alen);
        rtn[alen]=0;
     }
     (*env)->ReleaseByteArrayElements(env, barr, ba,0);
     return rtn;
}
/*
 * Class:     com_rocky_passdata_jni_JNI
 * Method:    string
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_rocky_passdata_jni_JNI_string
  (JNIEnv *env, jobject clazz, jstring str)
{
    char *cstr = _JString2CStr(env, str);
    int len = strlen(cstr);
    int i;
    for (i = 0; i < len; i ++)
    {
        *(cstr + i) += 1;
    }
    return (*env)->NewStringUTF(env, cstr);
}
JNIEXPORT jintArray JNICALL Java_com_rocky_passdata_jni_JNI_intArrayElements
  (JNIEnv *env, jobject clazz, jintArray array)
{
    int i;
    jsize len = (*env)->GetArrayLength(env, array);
    int *elements = (*env)->GetIntArrayElements(env, array, NULL);
    for (i = 0; i < len; i ++)
    {
        *(elements + i) += 10;
    }
    return array;
}

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := pass_data
LOCAL_SRC_FILES := pass_data.c
include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_ABI := all
APP_PLATFORM := android-19

 

posted @ 2016-12-22 18:30  Youxian  阅读(207)  评论(0)    收藏  举报