安卓复习之旅—使用NDK进行JNI编程

jni编程是进阶必不可少的技能,今天就一起回顾一下使用NDK进行jni编程的步骤:

step1.下载配置NDK

具体怎么配置我就不啰嗦了,提供一个下载地址:http://pan.baidu.com/s/1mhMX70O

step2.声明native方法

新建一个类,声明native方法:

/**
 * 声明native方法
 */
public class JniTest {
    static {
        System.loadLibrary("jni-test");
    }

    public static void main(String args[]) {
        JniTest jniTest = new JniTest();
        System.out.print(jniTest.getFromJni());
        jniTest.setIntoJni("hello world");
    }

    public native String getFromJni();

    public native void setIntoJni(String info);
}

由native 修饰的就是我们声明的本地方法:

step.3编译源文件得到.class文件,导出.h头文件

先看看工程目录:D:/as/UIdemo/JniDemo/jni_lib/src/main/java/com/example/jniTest.java
通过cmd 进入到合适的目录位置,为什么会说合适的位置呢,因为如果不在合适的位置的话 后面的javah命令可能会报一些错,这里我们进入到D:/as/UIdemo/JniDemo/jni_lib/src/main/java这个目录就可以了,然后进行编译:
这里写图片描述
这样就得到了.class文件和.h头文件:
这里写图片描述
进入.h文件中看看是怎样的:

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

#ifndef _Included_com_lin_jnidemo_JniTest
#define _Included_com_lin_jnidemo_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_lin_jnidemo_JniTest
 * Method:    getFromJni
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_lin_jnidemo_JniTest_getFromJni
  (JNIEnv *, jobject);

/*
 * Class:     com_lin_jnidemo_JniTest
 * Method:    setIntoJni
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_lin_jnidemo_JniTest_setIntoJni
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

  • 在.h头文件中函数名格式是Java_包名类名方法名;
  • JNIEnv *表示一个指向JNI环境的指针,通过它可以访问JNI接口提供的方法;
  • jobject:表示Java中的this;
  • JNIEXPORT 和 JNICALL:JNI中所定义的宏;
  • extern “C”:表示内部的函数采用c语言的命名风格来编译

step4.实现声明的native方法,配置Android.mk和Application.mk文件

在工程的主目录下创建一个子目录,然后将.h头文件复制到此目录中,接着创建test.c、Android.mk和Application.mk文件;
test.c如下:

/*
#include是编译预处理指令,就是在编译前将stdio.h这个文件里
的函数都添加到你写的cpp文件中,然后参与编译,生成.obj文件。
如果没有这个指令,你用到的一些方法时编辑器就会报错:
*/
#include <jni.h>
#include <stdio.h>


 jstring  Java_com_lin_jnidemo_JniTest_getFromJni
  (JNIEnv *env, jobject thiz){
   printf("getFromJni is load")
   return (*env)->NewStringUTF(env, "i am from jni ");
  };

 void  Java_com_lin_jnidemo_JniTest_setIntoJni
  (JNIEnv *env, jobject thiz, jstring string){
  printf("setIntoJni is load")
  (*env)->ReleaseStringUTFChars(env, string, "setintojni");
  };

Android.mk

LOCAL_PATH:= $(call my-dir)

#清除之前的一些系统变量
include $(CLEAR_VARS)

# 编译的源文件
LOCAL_SRC_FILES:=test.c

# 编译生成的目标对象  用来给java调用的模块名,
LOCAL_MODULE := jni-test

#指明要编译成动态库
include $(BUILD_SHARED_LIBRARY)

Application.mk:

#默认情况下NDK会编译产生各个CPU平台的so库
#指定so库的CPU平台的类型 all标识编译所有平台
APP_ABI := all

APP_ABI 可以指定so库的CPU平台的类型,常见的架构平台有armeabi,x86和mips,编译的时候尽量这三种都编译,以免在不同cpu平台报出UnsatisfiedLinkError 错误;

5.通过ndk-build命令编译产生so库文件
准备工作已经差不多了,接下来通过ndk-build命令编译产生so库文件:

这里写图片描述

这个时候在主目录会自动生成libs目录和obj目录,里面装的就是生成的so库文件:
这里写图片描述

到此一个基本的通过NDK进行JNI编程就完成了,看一下运行效果:
这里写图片描述

github

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值