android学习之jni编程初探

时间:2022-01-09 08:58:53

使“java+c”的开发方式成为了官方支持的开发方式,NDK的本质就是为了让Android应用程序能方便的使用JNI技术而提供的一套工具集合,使用NDK主要是4大好处,第一个,代码的保护,,由于apk的java层代码很容易被反编译,而c/c++反汇编难度较大;第二个,可以很方便的使用开源库,因为很多的现存的开源库都是c/c++代码编写的;第三个,提高程序的执行效率,第四个,便于移植,使用c/c++写的库可以方便在其它的嵌入式平台上使用.这里还有一个问题就是如果在模拟器上运行的话,我们只能在ARM上运行,并不能在intel上运行,否则会无法加载那个so库文件

NDK环境搭建

第一步:下载NDK

第二步:创建一个Android工程

第三步:在该工程目录的根目录下创建一个jni目录,用来作为ndk的编译路径(NDK的脚本会根据jni目录中的c/c++文件以及mk文件进行编译生成so文件)

第四步:创建builder(builder会使用ndk中的工具将jni目录中的文件编译成为so文件)Project->Properties->Builders->New->Program

android学习之jni编程初探



android学习之jni编程初探


android学习之jni编程初探


对了,这段代码实现的功能就是进行两个int的加减,

这里我们首先需要建立一个java文件

package com.jk.ndkdemo;

public class NDKBridge {
public native int add(int a,int b);

}

然后我们通过jdk中javah工具,根据NDKBridge类生成.h,在使用命令行时,我们要先进入到bin\clsses javah com.jk.ndkdemo.NDKBridge,生成的.h的命名的规则是包名_类名.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jk_ndkdemo_NDKBridge */

#ifndef _Included_com_jk_ndkdemo_NDKBridge
#define _Included_com_jk_ndkdemo_NDKBridge
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jk_ndkdemo_NDKBridge
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_jk_ndkdemo_NDKBridge_add
(JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

接下来我们根据h文件中的内容,在jni目录中创建c文件

#include "com_jk_ndkdemo_NDKBridge.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT jint JNICALL Java_com_jk_ndkdemo_NDKBridge_add
(JNIEnv *env, jobject obj, jint a, jint b)
{
//将jni类型转换成C类型
int a1 = a;
int b1 = b;

int c1 = a1 + b1;

//将C类型转成JNI类型
jint c = c1;
return c;
}
#ifdef __cplusplus
}
#endif
然后我们创建mk文件

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

这里的LOCAL_MODULE就是我们生成的so文件的名字,LOCAL_SRC_FILES就是我们根据这个文件来创建的,一旦我们保存,那么就会自动生成so文件

android学习之jni编程初探

然后我们就需要先加载so文件,然后就可以使用了,这个步骤在activity中实现

package com.jk.ndkdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {
// 加载so文件
static {
System.loadLibrary("MyNDKDemo");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获得含有jni方法的对象
NDKBridge bridge = new NDKBridge();
// 调用jni方法
int t = bridge.add(3, 5);
Toast.makeText(this, "" + t, Toast.LENGTH_SHORT).show();
}

}

好了,一个简单的jni编程就完成了。