在eclipse中进行Android下JNI开发的步骤

来源:互联网 发布:node path resolve 编辑:程序博客网 时间:2024/04/25 19:28

android下JNI开发

what 什么是JNI

  • JNI java native interface native本地 java本地接口
  • 通过JNI可以实现java和本地代码之间相互调用
  • jni可以看做是翻译 实际上就是一套协议

why 为什么要用JNI

  • Java 一处编译到处运行
    • ①java运行在虚拟机上 JNI可以扩展java虚拟机的能力 让java代码可以调用驱动
    • ②java是解释型语言 运行效率相对较低 C/C++的效率要高很多 通过jni把耗时操作方法C/C++可以提高java运行效率
    • ③ java代码编译成的.class 文件安全性较差, 可以通过jni 把重要的业务逻辑放到c/c++去实现,c/c++反编译比较困难 安全性较高
  • C历史悠久 1972年C 通过JNI可以调用优秀的C开源类库

How 怎么用JNI

  • java
  • c/c++ 能看懂 会调用
  • JNI开发流程 NDK native develop kit

要求

  • eclipse中配置有C/C++的工作环境。
  • 电脑配置好ndk的环境变量。ndk不用安装,直接解压然后将解压目录配置到path中即可。
  • ndk32位和62位版本

步骤

  • ①新建安卓工程,在MainActivity中用native关键字声明本地方法体。
  • ②在项目名右键新建jni文件夹,在该文件夹下新建hello.c,用于写C的代码。
#include<stdio.h>#include<stdlib.h>//本地函数命名规则: 返回值 Java_包名_类名_本地方法名,此方法左右为返回一个字符串jstring Java_com_zhong_jnitexst_MainActivity_helloFromC(JNIEnv* env,        jobject thiz) {    char* cstr = "Hello from C";    return (*env)->NewStringUTF(env, cstr);}
  • ③在jni目录下新建Android.mk文件。
LOCAL_PATH := $(call my-dir)    include $(CLEAR_VARS)#   指定生成的.so文件的名称    LOCAL_MODULE    := hello#    本地的C代码    LOCAL_SRC_FILES := hello.c    include $(BUILD_SHARED_LIBRARY)
  • ④编译C文件,编译之前要确保已将ndk的解压目录配置到path环境变量中,确定是否配置好的做法为在命令行输入ndk-build,出现如图所示即为配置好了。
    这里写图片描述
    然后在命令行界面进入到项目目录下,输入命令ndk-build并回车。会出现如下图所示:
    这里写图片描述

解除此错误的方法很简单,在C文件头部增加语句:

#include<jni.h>

然后在输入ndk-build,编译成功:
这里写图片描述

  • ⑤刷新工程,会发现libs目录下生成了so文件,接下来就是加载这个so文件。其中我们指定生成的是hello.so文件,这里生成的是libhello.so文件,多余部分是系统自动加上去的。
    这里写图片描述

  • ⑥加载.so文件,运行程序。在MainActivity中使用静态代码块加载.so文件,然后在MainActivity中调用用native关键字声明的本地方法,进而调到用C写的代码,这样就实现了在Java中调用C代码的需求。

public class MainActivity extends Activity {    //加载.so文件    static{        System.loadLibrary("hello");    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public native String hello();    public void click1(View v){        String hello = hello();        System.out.println(hello+"FFuu");    }}

注意:

这里默认生成的是arm环境下的.so文件,所以必须运行在arm的模拟器上,而不能运行在x86的模拟器上。

JNI开发的简便流程

  • 上面所示的过成比较复杂,这里介绍在eclipse中进行JNI开发的简便流程。

步骤:

  • ①同样的新建工程,写好native声明的本地方法。
  • ②右键工程目录选择Android tools –>Add Native Support ,这时会跳出一个选项卡,
    这里写图片描述

如果出现Finish不能点击的情况,配置一下ndk的目录就可以了。
这里写图片描述

  • ③这样,系统就会自动生成jni目录,并在目录下生成.c文件和Android.mk文件,注意这里有些eclipse版本会生成.cpp文件,因此要将生成的.cpp文件改为.c文件,Android.mk中也要做相应修改。
  • ④用Javah生成头文件。在命令提示符中进入到工程目录下src目录,然后键入javah命令,再将MainActivity(因为本地方法声明在MainActivity中)的完整路径作为参数传入,按回车,刷新工程,系统就会生成一个头文件,里面包含了命好名的本地方法,我们复制里面的方法到.c文件中。
    这里写图片描述
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_zhong_jnieasy_MainActivity */#ifndef _Included_com_zhong_jnieasy_MainActivity#define _Included_com_zhong_jnieasy_MainActivity#ifdef __cplusplusextern "C" {#endif/* * Class:     com_zhong_jnieasy_MainActivity * Method:    hello * Signature: ()Ljava/lang/String; *///将生成的方法复制到.c文件中,补上形参和返回值JNIEXPORT jstring JNICALL Java_com_zhong_jnieasy_MainActivity_hello  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

至此就可以将头文件删除了,如果复制到.c文件中代码报错后,可按如下步骤解决错误,右键工程–>Properties–>C/C++ General–>Paths and Symbols–>Icludes选项卡–>Add,在弹出的提示框中选择File system选择ndk目录下的include文件夹:G:\tools\ndk\android-ndk-r9d\platforms\android-14\arch-arm\usr\include,14对应的是我的最小的版本。如还报错,则可将工程关闭后再打开。

  • ⑤写完.c文件中方法的实现后,可在C/C++试图中点击小锤子按钮构建.c文件,生成.so文件,然后加载.so文件运行程序。
    这里写图片描述

  • ⑥这里默认仍是只生成arm环境下的.so文件,可在jni目录下新建Application.mk文件,在里面指定生成所有环境下的.so文件和安卓版本。

//生成所有环境下的.so文件APP_ABI := allAPP_PLATFORM := android-16
0 0