我的Android笔记--Hello Jni
来源:互联网 发布:windows 编译so 编辑:程序博客网 时间:2024/06/05 10:38
本人在学习NDK开发的时候,走了很多弯路,连一个普通Hello Jni的Demo都写不出来,网上也有很多相关资料,但是我比较笨,一直学不会。现在整理下思绪,分享一下如何写一个Hello Jni的小Demo,希望能帮到有需要的朋友。另外感叹一下,学习新东西并不难,难就难在没有思绪,毫无进展和难以坚持。成就感是最好的学习动力,如果在每个阶段都能有所收获,那么学习将会是一件很快乐的事情。
JNI
Java Native Interface,它提供了若干接口实现了Java语言和C&C++(主要的)的通信。官方的学习资料有Oracle的Java Native Interface Specification等,看这个文档很要命啊,不过也让我的阅读能力有了很大长进。国内的学习资料目前好像比较少,我在网上搜到了一篇叫《JNI完全技术手册》的很有帮助。
- 编写Java类并生成头文件
- 编写c语言文件
- 编写Android.mk和Application.mk文件
- 编译成动态库并调用
编写Java类
我这里使用C语言进行开发,IDE是Android studio,ndk版本是r12,另外需要在在Path中配置sdk和ndk的路径,否则使用起来比较麻烦。
首先,编写一个类,名字叫HelloJNI,在里面完成以下代码。
package cn.wdh.myself.hellojni.utils;public class HelloJNI { static { System.loadLibrary("hellojni"); } public static native String getString();}
然后,进入到该Java文件的目录中去,生成.class文件,然后退出到cn文件夹的父目录,也就是module中的java目录,使用
javah -jni cn.wdh.myself.hellojni.utils.HelloJNI
命令,生成一个头文件,这个时候,他的文件名应该叫
cn_wdh_myself_hellojni_utils_HelloJNI.h
这个文件名是根据的类全名生成的,里面的内容是根据你的Java文件中定义的方法生成的。我的头文件的内容如下
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class cn_wdh_myself_hellojni_utils_HelloJNI */#ifndef _Included_cn_wdh_myself_hellojni_utils_HelloJNI#define _Included_cn_wdh_myself_hellojni_utils_HelloJNI#ifdef __cplusplusextern "C" {#endif/* * Class: cn_wdh_myself_hellojni_utils_HelloJNI * Method: getString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_cn_wdh_myself_hellojni_utils_HelloJNI_getString (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
注意上文件内容,在extern “C” {}的这个括号里面,定义了Java类中哪些使用C语言(或其他语言)编写的方法。这个头文件我们可以自己写,但是为了省事,使用javah -jni命令生成的头文件还是很方便和安全的,不必为拼写错误烦恼。
另外,很多教程里面并没有该头文件的名称,其实这个头文件不必要这么长,头文件名称只要符合命名规则,长短是无所谓,为了编写C语言文件方便,我们将其改为hello.h。然后在module下,新建一个jni文件夹,将头文件丢进去。
编写C文件
在jni文件夹下,新建一个C文件,后缀是.c,文件名前缀和刚才生成并更改的头文件同名也叫hello。下面是代码内容
#include "hello.h"#include <stdio.h>JNIEXPORT jstring JNICALL Java_cn_wdh_myself_hellojni_utils_HelloJNI_getString(JNIEnv *env, jclass jc){ return (*env)->NewStringUTF(env,"Hello JNI!");}
方法名是从头文件中复制过来的,我们只要把形参写上就好了,方法体中的函数是JNI提供的一个方法,在Oracle的Java Native Interface Specification中列出了该接口提供的所有方法。
编写Android.mk文件
使用NDK开发,Android.mk文件的编写是关键,关于Android.mk的语法,Google提供的Android Developer有详细说明,下面是官网
https://developer.android.com/ndk/guides/android_mk.html[Android.mk语法]
文件同样放置在jni文件夹下,下面是Hello Jni工程的Android.mk文件的内容
#开头必须这么写LOCAL_PATH := $(call my-dir)#编译模块之前必须调用下面的语句include $(CLEAR_VARS)#指定生成的库文件名称LOCAL_MODULE = hellojni#指定源代码文件LOCAL_SRC_FILES = hello.c#编译的目标CPU架构库,all生成全部7个TARGET_ARCH_ABI = all#编译动态库include $(BUILD_SHARED_LIBRARY)
另外Application.mk在这个Demo中暂时用不到,他的语法在上面Android.mk中有跳转。
编译和引用
完成以上代码文件编写以后,我们只需要打开命令行串口,cd到项目的jni文件夹下面,使用ndk-build命令,就可以生成相应的动态库文件,后缀名是.so,我们只需要在项目main文件夹下面新建一个jniLIbs文件夹,然后将.so库放置进去即可。
后话
使用JNI配合NDK工具开发可以解决很多使用纯SDK开发解决不了的问题。例如加密解密,使用c进行文件加密解密的性能比使用java更快速,并且更难以被反编译获取加密和解密规则;我们也可以将用其他开源库编译到我们的项目中来,完成一些android平台提供不了的功能等等等。
哎,敲了这么长时间代码,真心觉得自己越来越low,岁数越来越大但却一事无成。技术也没长进,另使用Android Studio配置ndk开发环境也可以直接生产相应的C文件,这里的教程也可适用于eclipse,导包方式略微不同。
- 我的Android笔记--Hello Jni
- android JNI 的Hello World
- Android NDK的入门学习Hello JNI
- Android JNI的使用 显示Hello Word
- Android: hello-jni
- Android Studio:Hello JNI
- Android NDK编程,我的第一个hello-jni程序,如何调用自己编译的so库
- jni的hello world
- anroid JNI 学习笔记 最简单的Hello
- Android JNI编程入门-hello jni
- 我的Android笔记(一)―― hello world程序结构分析 - Android移动开发技术文章
- android ndk(一) hello-jni
- Android JNI写出Hello World
- android中导入hello-jni文件时遇到的问题
- Android开发之NDK/JNI的hello world
- 我的Android笔记(一)—— hello world程序结构分析
- 我的第一个Android JNI程序
- Android的Hello World结构-笔记
- 视频直播技术详解(3)编码和封装
- spark学习笔记1 spark算子
- hibernate连接mysql配置文件
- 17. Letter Combinations of a Phone Number
- hibernate 乐观锁与悲观锁使用
- 我的Android笔记--Hello Jni
- hibernate配置多数据源
- 视频直播技术详解(4)推流和传输
- NetworkManagerHUD源代码
- UNIX 个人常用命令积累
- nRF51822SDK中db_discovery学习笔记
- apt-get指令
- HDU3591-The trouble of Xiaoqian
- leetcode之387. First Unique Character in a String(C++解法)