文档章节

JNI 入门

 草帽行者
发布于 2017/04/28 10:42
字数 708
阅读 16
收藏 0
点赞 0
评论 0

JNI 入门

[TOC]

环境

anddroid studio 2.2

安装: NDK,CMake,LLDB

Android Studio

准备工作

  1. 配置ndk目录

local.properties

```
# header note.
#Mon Mar 20 15:50:38 CST 2017
ndk.dir=/Users/cj/Library/Android/sdk/ndk-bundle
```
  1. 兼容老的ndk

gradle.properties

```
# org.gradle.parallel=true
# 兼容老的ndk
android.useDeprecatedNdk="true"
```

使用步骤

  1. 使用java文件创建一个native方法,用于调用c代码对应的方法:Jni.java

    	public class Jni {
    
    	public native String sayHello();
    
    	}
    
  2. 创建存放c/c++文件的目录jni

main/jni

  1. 创建.c文件:hello.c

main/jni/hello.c

  1. 添加头文件:hello.c

    	#include <stdio.h>
    	#include <stdlib.h>
    	#include <jni.h>
    
  2. 编写供java调用的方法: hello.c

方法名:已java文件为标准 --> Java_包名_类名_方法名

```
/**
* 方法名命名规则:Java_包名(点换成下划线)_类名_方法名
* jstring:返回值
* JNIEnv:相当于类库,里面有很多方法
* jobject:  谁调用这个方法就是谁的实例
*/
jstring Java_com_myc_jni_Jni_sayHello(JNIEnv *env, jobject instance) {
	char *text = "Hello Jni";
	return (*env)->NewStringUTF(env, text);
}
```

or

```
JNIEXPORT jstring JNICALL
Java_com_myc_jni_Jni_sayHello(JNIEnv *env, jobject instance) {
    char *txt = "Hello Jni";
    return (*env)->NewStringUTF(env, txt);
}
```
  1. 指定编译不同的CPU

app/build.gradle

```
defaultConfig {
    ...

    ndk{
        moduleName "Hello"  // 生产的so文件名:lib+moduleName+.so
        abiFilters "armeabi","armeabi-v7a","x86"    // cpu的类型
    }
}
```
  1. 加载动态链接库:Jni.java

链接库的名字为build.gradle配置的moduleName

```
public class Jni {
	{
    	System.loadLibrary("Hello");    
	}

	...
}
```
  1. 使用_java调c

    • 本项目中使用: 通过new Jni(),然后调用其中的方法 导出:Rebuild project

      app --> build --> intermediates --> ndk --> debug --> lib

    • 外部使用

      1. 将对应的cpu的so文件放入到libs目录中

      2. 将so文件导入项目,修改build.gradle,添加如下配置信息

      导入成功:切换到android视图下,我们可以看到app目录下自动生成了一个jniLibs目录,打开该目录,可以看到我们导入的so

        ```
        android {
        	...
      
        	sourceSets {
        		main {
            		jniLibs.srcDirs = ['libs']
        	}
        }
        ```
      
      1. 在当前项目中(src/main/java)创建一个新包,报名为so库编译native时使用的包名,然后再在该包下新建.java文件,eg:JniOther.java

        	public class JniOther {
        
        		/**
        		* 加载动态链接库
        		*/
        		{
        			System.loadLibrary("Hello");    // 名字:build.gradle文件中的moduleName
        		}
        
        		/**
        		* so 提供的方法
        		* @return
        		*/
        		public native String sayHello();
        
        	}
        
      2. 使用: new JniOther() 调用相关的native方法

  2. 使用_c调java

    1. 准备工作:

      • java文件中存在方法addJava(int a, int b)
      	public int addJava(int a, int b) {
          return a + b;
      }
      
      • 准备一个java调c的方法:cAddJava()
      	public native int cAddJava();
      
      
    2. 在c文件中实现方法:cAddJava() a. 得到类字节码

      b. 得到方法,最后一个参数是方法签名(见博客:方法签名)

      c. 实例化该类

      d. 调用方法

      	JNIEXPORT jint JNICALL
      	Java_com_myc_jni_Jni_cAddJava(JNIEnv *env, jobject instance) {
      	    // 1. 得到字节码
      	    jclass jclass1 = (*env)->FindClass(env, "com/myc/jni/Jni");
      	    // 2. 得到方法,最后一个参数是方法签名  int addJava(int a, int b)
      	    jmethodID methodID = (*env)->GetMethodID(env, jclass1, "addJava", "(II)I");
      	    // 3. 实例化该类
      	    jobject jobj = (*env)->AllocObject(env, jclass1);
      
      	    // 4. 调用方法
      	    return (*env)->CallIntMethod(env,jobj,methodID,13,12);
      	}
      
    3. 测试

      	int cAdd = jni.cAddJava();
      System.out.println("---c调用java:" + cAdd);
      
      // 结果
      I/System.out: ---c调用java:25
      

© 著作权归作者所有

共有 人打赏支持
粉丝 6
博文 28
码字总数 29999
作品 0
广州
程序员
JNI 开发指南

Android JNI编程提高篇之二 Android JNI编程提高篇之一 Android JNI开发入门之二 Android JNI开发入门之一

zungyiu ⋅ 2011/12/18 ⋅ 0

Android NDK 原理

本文介绍Android NDK 原理, 熟悉此教程, 需要有JNI的基础, 以及Android 应用程序的入门知识(环境搭建, 工程运行等), 可以查看本站的其它文章. 本文关注Android NDK的原理知识. 关于JNI的基本...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

Android NDK 原理

本文介绍Android NDK 原理, 熟悉此教程, 需要有JNI的基础, 以及Android 应用程序的入门知识(环境搭建, 工程运行等), 可以查看本站的其它文章. 本文关注Android NDK的原理知识. 关于JNI的基本...

晨曦之光 ⋅ 2012/03/07 ⋅ 0

用Android NDK编译FFmpeg

原文转自:http://abitno.me/compile-ffmpeg-android-ndk Android内置的编解码器实在太少,于是我们需要FFmpeg。Android提供了NDK,为我们使用FFmpeg这种C语言代码提供了方便。 不过为了用N...

华宰 ⋅ 2011/09/08 ⋅ 1

Android NDK 入门

原文转自:http://abitno.me/a-simple-tutorial-to-android-ndk 我理解的NDK是允许你把程序的一部分代码用C或C++来实现,通过JNI与Java代码交互。不要想整个程序都用C/C++完成,Android是不允...

华宰 ⋅ 2011/09/08 ⋅ 1

【jni 编程】—— NDK环境搭建

在《站在巨人的肩膀上,谈app的创新性》一文中 http://my.oschina.net/liusicong/blog/311971,我提到过构建app技术壁垒的必要性。在构建技术壁垒时,我们往往需要调用许多库函数,例如:图像...

刘小米 ⋅ 2014/09/10 ⋅ 0

Android NDK 入门与实践

Android NDK 入门与实践 吴小龙同學2017-12-271 阅读 NDK NDK 是什么 NDK 全称 Native Development Kit,可以让您在 Android 应用中调用 C 和 C++ 代码的工具。 NDK 好处 1、NDK 可以生成 .s...

吴小龙同學 ⋅ 2017/12/27 ⋅ 0

Android: NDK编程入门笔记

为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。 2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C...

gongweixin ⋅ 2013/04/23 ⋅ 3

JNI 简单入门

做Android开发,最終还是免不了要用NDK的,我这才真的需要学习下JNI。简单的说,JNI就是让Java代码与native代码(比如C和C++)交互的一种机制。 参照The JNI Programmer's Guide and Specif...

华宰 ⋅ 2011/09/08 ⋅ 2

Android: NDK编程入门笔记

为何要用到NDK? 概括来说主要分为以下几种情况: 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。 2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C...

xubohui ⋅ 2012/08/20 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kubeflow实战系列:利用TFJob导出分布式TensorFlow模型

介绍 本系列将介绍如何在阿里云容器服务上运行Kubeflow, 本文介绍如何使用TfJob导出分布式模型训练模型。 第一篇:阿里云上使用JupyterHub 第二篇:阿里云上小试TFJob 第三篇:利用TFJob运行...

全部原谅 ⋅ 19分钟前 ⋅ 0

007. 深入JVM学习—老年代

老年代空间的主要目的是用于存储由Eden发送来的对象,一般在经历好几次“Minor GC”还会保存下来的对象,才会被复制到老年代,这样就可以存放更多的对象,同时在老年代中执行GC的次数也相对较...

影狼 ⋅ 20分钟前 ⋅ 0

常见的一些C#开源框架或者开源项目

原:https://blog.csdn.net/qq_27825451/article/details/70666044 Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更......

whoisliang ⋅ 21分钟前 ⋅ 0

设计模式基本原理

刚开始接触编程这行的时候看过设计模式,当时感觉学这些模式没有太大的用处,当时也看不太懂。但是随着慢慢接触这一行,经过一段时间的编程以后,再回过头来看设计模式,发现设计模式的确是太...

王子城 ⋅ 24分钟前 ⋅ 0

阿里云全面支持IPv6!一文揽尽4位大咖精彩演讲

摘要: 自从去年11月以来,阿里巴巴高度重视数据中心的网络改造、云产品改造、应用及网络改造等多个维度,经过半年以来的建设,阿里云已经完成了域名解析等关键产品的分析,现在阿里云已经完...

传授知识的天使 ⋅ 35分钟前 ⋅ 0

windows Android sdk 配置

1、下载Android SDK,点击安装,直接默认路径即可! 下载地址:http://developer.android.com/sdk/index.html 2、默认路径安装后,安装完成,开始配置环境变量。 3、打开计算机属性——高级系...

阿豪boy ⋅ 37分钟前 ⋅ 0

bash shell script 简明教程

User <--> bash <--> kernel shell is not kernel or part of kernel various shells: tcsh, csh, bash, ksh find the using shell: echo $SHELL find all the shells: cat /etc/shells what......

mskk ⋅ 40分钟前 ⋅ 0

Service Mesh简史

William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公...

好雨云帮 ⋅ 40分钟前 ⋅ 0

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 52分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 53分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部