Android Studio JNI使用之个人笔记

JNI数据类型

上面我们提到JNI定义了一些自己的数据类型。这些数据类型是衔接Java层和C/C++层的,如果有一个对象传递下来,那么对于C/C++来说是没办法识别这个对象的,同样的如果C/C++的指针对于Java层来说它也是没办法识别的,那么就需要JNI进行匹配,所以需要定义一些自己的数据类型。

1.原始数据类型

Java Type Native Typ Description
boolean jboolean unsigned 8 bits
byte jbyte signed 8 bits
char jchar unsigned 16 bits
short jshort signed 16 bits
int jint signed 32 bits
long jlong signed 64 bits
float jfloat 32 bits
double jdouble 64 bits
void void N/A

2.引用类型

 前面我们在获取AndroidJni对象的使用通过定义jclass引用,然后调用FindClass函数获取了该对象,所以JNI也定义了一些引用类型以便JNI层调用,具体的引用类型如下:

jobject                     (all Java objects)
|
|-- jclass                    (java.lang.Class objects)
|-- jstring                    (java.lang.String objects)
|-- jarray                    (array)
|      |--jobjectArray       (object arrays)
|      |--jbooleanArray        (boolean arrays)
|      |--jbyteArray            (byte arrays)
|      |--jcharArray            (char arrays)
|      |--jshortArray        (short arrays)
|      |--jintArray            (int arrays)
|     |--jlongArray            (long arrays)
|      |--jfloatArray        (float arrays)
|      |--jdoubleArray         (double arrays)
|
|--jthrowable

3.方法和变量的ID
 当需要调用Java中的某个方法的时候我们首先要获取它的ID,根据ID调用JNI函数获取该方法,变量的获取过程也是同样的过程,这些ID的结构体定义如下:

struct _jfieldID;              /* opaque structure */ 
typedef struct _jfieldID *jfieldID;   /* field IDs */ 

struct _jmethodID;              /* opaque structure */ 
typedef struct _jmethodID *jmethodID; /* method IDs */

Android Stduio中JNI应用

新建JniUtils类实现native方法

public class JniUtils {
    public static native String getStringFormC();
}

然后clean project 再rebuild project 生成class文件,


再打开Terminal输入指令
cd app\src\main
然后再输入指令
javah -d jni -classpath ..\..\build\intermediates\classes\debugcom.dongdong.ndkjnidemo.JniUtils

这个时候在src/main/jni下就会生成.h文件,新建一个c类随便取一个名字,添加代码如下

#include "stdio.h" 
#include "stdlib.h" 
#include "com_dongdong_ndkjnidemo_JniUtils.h" 
/* * Class: Java_com_dongdong_ndkjnidemo_JniUtils * Method: getStringFormC * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_dongdong_ndkjnidemo_JniUtils_getStringFormC (JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env,"这里是来自c的string");

这里发现头文件#include <jni.h>报红色,是因为咱们还没有配置ndk环境,打开file->project structure选择你所下载的ndk环境路径

设置好了之后,发现头文件还是红色的,然后再build一下工程,就会有提示

Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.

按着提示做就行了 在gradle.properties文件末尾添加android.useDeprecatedNdk=true就ok啦
然后在app文件下得build.gradle ->defaultConfig括号内添加如下代码

ndk {
            moduleName "Lib"
            ldLibs "log"
            abiFilters "armeabi", "armeabi-v7a"
       }//输出指定三种abi体系结构下的so库,目前可有可无。

到了这一步重新build项目,发现已经没有变红了。接下来就是运用了,在JniUtils类里面添加如下代码

static {    
   System.loadLibrary("NdkJniDemo");//之前在build.gradle里面设置的so名字,必须一致
}

然后简单调用就行了,MainActivity代码如下

public class MainActivity extends AppCompatActivity { 
   TextView textView;    
@Override    protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.ndk_text);
        textView.setText(JniUtils.getStringFormC());
    }
}

咱们打开app->intermediates-ndk-debug发现生成了三个文件夹,并且对应了之前我们在build.gradle配置的abiFilters
大功告成。

Eclipse下需要cd 项目目录 javah -d jni -classpath bin/classes com.dongdong.utils.MainActvity生成.h文件。创建.c文件实现相关代码。修改.mk文件。其中
LOCAL_MODULE     := ApkPatchLibrary     //库名称
Android.mk文件LOCAL_SRC_FILES  := com_dongdong_utils_MainActvity.c  C文件
LOCAL_LDLIBS     := -lz -llog  //Android 日志配置

Application.mkAPP_ABI:=armeabi armeabi-v7a arm64-v8a  //编译的平台

最后cd 项目目录 执行ndk-build命令即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值