Android Studio使用JNI

1. 添加native接口

static{
System.loadLibrary("JniTest");
}

private native int Add(double num1,double num2);
private native int Sub(double num1,double num2);
private native int Mul(double num1,double num2);
private native int Div(double num1,double num2);

2.Build->Make Project
验证工程中并无其他错误,并对工程进行编译,生成.class文件
在Build/intermediates/classes/debug里面

3.javah 生成.h文件

在工程的app/src/main/java 目录下
cmd 执行 javah com.example.caculate.MainActivity 命令,就会生成.h文件
建立jni目录,将.h拷贝进去

4.jni目录下实现.c
新建一个.c 实现.h中的函数

5.Build->Make Project

会报错
在local.properties文件中增加ndk的路径
sdk.dir=C\:\\Users\\Alif\\AppData\\Local\\Android\\Sdk
ndk.dir=I\:\\Android\\android-ndk-r11c

在app下面的build.gradle里面增加 so的名称
\app\build.gradle
ndk {
moduleName "JniTest"
abiFilters "armeabi", "armeabi-v7a", "x86"
}

6.Build->Make Project 就可以编译出so文件了
生成的so在app/Build/intermediates/ndk/debug/lib下面

我们在jni目录下增加一个Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniTest
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)

然后ndk-build 生成libs目录

将libs目录名称改为 jniLibs 就会自动打包到apk里面了

.h和.c文件

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

#ifndef _Included_com_example_caculate_MainActivity
#define _Included_com_example_caculate_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_caculate_MainActivity
 * Method:    Add
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_example_caculate_MainActivity_Add
  (JNIEnv *, jobject, jdouble, jdouble);

/*
 * Class:     com_example_caculate_MainActivity
 * Method:    Sub
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_example_caculate_MainActivity_Sub
  (JNIEnv *, jobject, jdouble, jdouble);

/*
 * Class:     com_example_caculate_MainActivity
 * Method:    Mul
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_example_caculate_MainActivity_Mul
  (JNIEnv *, jobject, jdouble, jdouble);

/*
 * Class:     com_example_caculate_MainActivity
 * Method:    Div
 * Signature: (DD)I
 */
JNIEXPORT jint JNICALL Java_com_example_caculate_MainActivity_Div
  (JNIEnv *, jobject, jdouble, jdouble);

#ifdef __cplusplus
}
#endif
#endif

#include <jni.h>
#define jintJNICALL
#ifndef _Included_com_example_caculate_MainActivity
#define _Included_com_example_caculate_MainActivity
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jintJNICALL Java_com_example_caculate_MainActivity_Add
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 + num2);
}

JNIEXPORT jintJNICALL Java_com_example_caculate_MainActivity_Sub
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 - num2);
}

JNIEXPORT jintJNICALL Java_com_example_caculate_MainActivity_Mul
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 * num2);
}

JNIEXPORT jintJNICALL Java_com_example_caculate_MainActivity_Div
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    if (num2 == 0) return 0;
    return (jint)(num1 / num2);
}
#ifdef __cplusplus
}
#endif
#endif

使用动态注册JNI

1.函数名称太长,因为是javah生成的头文件,名称太长
2.每一个类都要javah一次,很麻烦

在jni目录下生成编写.c

#include <jni.h>
#include <stdio.h>
//#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

JNIEXPORT jint JNICALL native_Add
(JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
return (jint)(num1 + num2 +1);
}

JNIEXPORT jint JNICALL native_Sub
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 - num2 +1);
}

JNIEXPORT jint JNICALL native_Mul
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    return (jint)(num1 * num2 +1);
}

JNIEXPORT jint JNICALL native_Div
        (JNIEnv *env, jobject obj, jdouble num1, jdouble num2)
{
    if (num2 == 0) return 0;
    return (jint)(num1 / num2 +1);
}

//Java和JNI函数的绑定表
static JNINativeMethod gMethods[] = {
        {"Add", "(DD)I", (void *)native_Add},
        {"Sub", "(DD)I", (void *)native_Sub},
        {"Mul", "(DD)I", (void *)native_Mul},
        {"Div", "(DD)I", (void *)native_Div},
};

//注册native方法到java中
static int registerNativeMethods(JNIEnv* env, const char* className,
                                JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;
    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL) {
        return JNI_FALSE;
    }
    if ((*env)->RegisterNatives(env, clazz, gMethods,numMethods) < 0){
        return JNI_FALSE;
    }

    return JNI_TRUE;
}

int register_ndk_load(JNIEnv *env)
{

    return registerNativeMethods(env, "com/example/caculate/MainActivity",
                                 gMethods,sizeof(gMethods) / sizeof(gMethods[0]));
                                 //NELEM(gMethods));
}

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return result;
    }

    register_ndk_load(env);

    // 返回jni的版本
    return JNI_VERSION_1_4;
}

编写Android.mk文件

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := JniTest_jni
LOCAL_SRC_FILES := MyJniCalc.c
LOCAL_SHARED_LIBRARIES := libandroid_runtime
include $(BUILD_SHARED_LIBRARY)

使用ndk-build生成so文件

还是移到jniLibs目录下

最后成功修改

78+11 +1 = 90

源码:http://pan.baidu.com/s/1kULyvDd   密码 m8ns

时间: 2024-11-17 04:25:26

Android Studio使用JNI的相关文章

Android Studio使用jni、so库

Android Studio使用jni.so库 在Android Studio1.1之后,AS就已经支持jni和so库了,马上发布的1.3正式版,更是可以在clion环境下编译c.c++,更加方便的使用NDK进行开发,网上有很多讲在Android Studio中使用jni的方法,但大多都是在1.1之前的,那时候还没有直接支持jni,所以需要通过给gradle增加task的方式来添加支持.而现在,这一切都不是事!!! 添加lib库 切换到project标签,直接将jar包复制到libs目录下,在添

Android Studio建立jni开发环境

声明: 文章参考自 csdn sodino 的博客 Step: 1. 添加native接口注意写好native接口和System.loadLibrary()即可了,并无特别之处. Step: 2.执行Build->Make Project生成了.class文件..class文件的生成路径是在 app_path/build/intermediates/classes/debug下的. 这个在android studio里面看不到, 到文件管理器里面翻到的, 里面还有好多东西. Step: 3.ja

Android Studio中JNI -- 1 -- 配置方法

1.配置NDK 1.1 下载NDK Android Studio 1.2 配 android-ndk-r10e,不同版本的Studio需要配置不同的ndk,下载完成后,随便解压放至某个文件目录下 1.2 指定NDK目录 1.3 修改build.gradle配置 需要修改的是在<Project>\app\build.gradle 2. 添加native接口 2.1 添加native 2.2 执行build -> Make Project 确定程序无错误,并生成.class文件 2.3 通过

Android Studio 开发JNI应用

Android的JNI开发主要有两中情况:一种是使用已经编译好的.so动态库:一种是使用c/c++源代码开发.下面分别介绍: 一.使用已经编译好的so 这种情况比较件简单,只要把的.so文件放到相应的目录即可.如下: .[module_name]         . . [src]         . . .[main]         . . . .[jniLibs]         . . . . .[armeabi]         . . . . .[armeabi-v7a]     

Android Studio 串口jni开发

1. 开发环境 Mac OS X , Android Studio 2.1.2 2. 创建新工程 创建SerialPortDemo工程, Minimum SDK 选择 API 19: Android 4.4. 3. 工程环境 ndk 路径使用默认的, gradle version 2.10 4. 切换工程显示方式 5.修改build.gradle 注意是与app目录同级的build.gradle 修改classpath 对应的版本,请参考:https://sites.google.com/a/a

Windows下利用Android Studio进行JNI开发准备

因为公司项目需要,要进行jni的开发,进行arr,acr音频格式转化,后期上项目代码,现在先上测试代码 其中参考了http://blog.csdn.net/sodino/article/details/41946607的书写,不过有些说的好含蓄,博主摸索了一个小时,现在把详细的细节分享给大家 首先,要去官方下载ndk,因为博主的机子是win7 64位,博主就贴上这个地址,其余的楼主没有查http://dl.google.com/android/ndk/android-ndk32-r10-wind

【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studio默认采用的却是gradle方式,与ADT编辑的方式大不相同,那再andorid studio中如何导入so文件呢? 在android studio 中我们可能会用到jar包和so文件的方式,对于jar包可能接触更多,只需要我们把工程转换为project显示方式,打开app下的libs文件夹,导入即

android studio 中jni底层日志的打印

1 添加ndk对log支持若需要添加ndk对log的支持,只需要通过以下2步即可实现. 1.1 修改Android.mk如生成的库文件是".so文件",则在Android.mk中添加如下内容:LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog如生成的库文件是".a文件",则在Android.mk中添加如下内容:LOCAL_LDLIBS:=-llog 1.2 在.c或.cpp文件中引用log头文件添加如下内容:// 引入log头文件#in

android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. ------------------------------------------------------------------------ (原创:转载声明出处:http://www.cnblogs.com/linguanh/) 1,过程感慨(想直接看教程,请跳过此部分) 在写具体内容之前,我先说下我搞这个东西的过程,由于导师之前说过要搞个图像匹配的androi A

Android Studio下jni应用

最近在将一个小应用从eclipse开发迁移到android studio,程序中有native代码实现,在eclipse是靠Android.mk这么个mk文件来组织编译的,但到android studio上就不行了,因其是靠gradle组织,所以makefile里的配置要转换为build.gradle里的语句(尽管实际上gradle也是组织一个mk文件),同时在迁移过程中遇到了一些问题,这里记录一下,以备后查. Android的JNI开发主要有两中情况:一种是使用已经编译好的.so动态库:一种是