jni的调用过程
1)安装和下载Cygwin,下载Android NDK
2)在ndk项目中JNI接口的设计
3)使用C/C++实现本地方法
4)JNI生成动态链接库.so文件
5)将动态链接库复制到java工程,在java工程中调用,运行java工程即可

NDK

1.NDK是一系列工具的集合,帮助开发者迅速的开发C/C++的动态库,并能自动将so和java应用打成apk包

2.NDK集成了交叉编译器,并提供了相应的mk文件和隔离cpu、平台等的差异,开发人员只需简单的修改mk文件就可以创建出so

交叉编译
  在一个平台下,编译出另一个平台能够执行的二进制的代码
  平台:windows,mac os,linux
  处理器:x86,arm,mips
交叉编译的原理
  源代码->编译->链接->可执行程序
  模拟其他平台的特性
交叉编译的工具链
  多个工具的集合,一个工具使用完后接着调用下一个工具

常见工具
  NDK:native developement kit:开发jni必备,就是模拟其他平台特性来编译代码的工具
  CDT:C/C++ developement tools:高亮显示c语言关键字
  cygwin:一个模拟器,可以再windows下运行linux指令

NDK目录结构
  docs:帮助文档
  build/tools:linux的批处理文件
  platforms:编译c代码需要使用的头文件和类库
  prebuilt:预编译使用的二进制可执行文件
  sample:jni的使用例子
  source:ndk的源码
  toolchains:工具链
  ndk-build.cmd:编译打包c代码的一个指令

* 使用C语言实现本地方法

1. 在项目根目录下创建jni文件夹
2. 在jni文件中创建一个c文件
3. 在java代码中,创建一个本地方法helloFromC

//native关键字
public native String helloFromC();

4. 在jni中定义函数实现这个方法,函数名必须为

//返回值 报名_类名_方法名(参数参照例子)
jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)

5. 返回一个字符串,用c定义一个字符串

char* cstr = "hello from c";

6. 把c的字符串转换成java的字符串

jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;

7. 在jni中创建Android.mk文件
8. 在c文件中添加<jni.h>头文件
9. 在jni文件夹下执行ndk-build.cmd指令
10. java代码中加载so类库,调用本地方法(so是C语言的类库)

static{
//加载打包完毕的so类库
System.loadLibrary("hello");
}

代码

MainActivity

public class MainActivity extends Activity {

    static{
//加载打包完毕的so类库
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void click(View v){
Toast.makeText(this, helloFromC(), 0).show();
} //定义一个本地方法,方法体由c语言实现
public native String helloFromC();
}

Hello.c

#include <stdio.h>
#include <stdlib.h>
#include <jni.h> jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj){
//c语言的字符串
char* cstr = "hello from c";
//把C语言的字符串转换成java的字符串
// jstring (*NewStringUTF)(JNIEnv*, const char*);
// jstring jstr = (*(*env)).NewStringUTF(env, cstr);
jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;
}

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
#编译生成的文件的类库叫什么名字
LOCAL_MODULE := hello
#要编译的c文件
LOCAL_SRC_FILES := Hello.c include $(BUILD_SHARED_LIBRARY)

* 实现两个数相加

public class MainActivity extends Activity {
static{
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void click(View v){
Toast.makeText(this, "3+5的和为" + add(3, 5), 0).show();
} public native int add(int i, int j); }

Android.mk

 LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := hello
LOCAL_SRC_FILES := Hello.c include $(BUILD_SHARED_LIBRARY)

Hello.c

#include <jni.h>

jint Java_com_itheima_helloworld2_MainActivity_add(JNIEnv* env, jobject obj, jint i, jint j){

    return i + j;
}

Application.mk

APP_ABI := all //支持arm、mips、x86等所有架构

* javah
  1.7:在src目录下执行javah 包名.类名
  1.6:在bin/classes目录下执行

然后工程刷新,复制里面已经自动生成的方法名,就可以粘贴到c文件中使用

* 配置NDK路径

perference->android->ndk

右键->android tools->add native support可以自动生成jni和mk文件

关联源码:properties->C/C++ general->paths and symbols(源码路径:ndk\platforms\android-18\arch-arm\usr\include)

* 传递整形数组

public class MainActivity extends Activity {

    static{
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} int[] arr = {1,2,3,4,5}; public void click(View v){
arrayEncode(arr);
for (int i : arr) {
System.out.println(i);
}
} public native void arrayEncode(int[] arr);
}

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello
LOCAL_SRC_FILES := hello.c include $(BUILD_SHARED_LIBRARY)

hello.c

#include <jni.h>

JNIEXPORT void JNICALL Java_com_itheima_array_MainActivity_arrayEncode
(JNIEnv * env, jobject obj, jintArray jintarr){
//拿到整型数组的长度以及第0个元素的地址
//jsize (*GetArrayLength)(JNIEnv*, jarray);
int length = (*env)->GetArrayLength(env, jintarr);
//jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
int* arrp = (*env)->GetIntArrayElements(env, jintarr, ); int i;
for(i = ;i < length; i++){
*(arrp + i) += ;
}
}

* 调用美图秀秀的本地方法(只需复制粘贴美图秀秀的so文件,并不需要创建jni文件)

public class MainActivity extends Activity {

    private Bitmap bm;
private ImageView iv; static{
System.loadLibrary("mtimage-jni");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); bm = BitmapFactory.decodeFile("sdcard/aneiyi.jpg");
iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bm);
} public void click(View v){
int width = bm.getWidth();
int height = bm.getHeight(); //用于保存所有像素信息
int[] pixels = new int[width * height];
//获取图片的像素颜色信息,保存至pixels
bm.getPixels(pixels, 0, width, 0, 0, width, height); JNI jni = new JNI();
//arg0:保存了所有像素颜色信息的数组
//arg1:图片的宽
//arg2:图片的高
//此方法是通过改变pixels的像素颜色值来实现美化效果
jni.StyleLomoC(pixels, width, height); Bitmap bmNew = Bitmap.createBitmap(pixels, width, height, bm.getConfig());
iv.setImageBitmap(bmNew);
}
}

* 在C代码中打印log日志

第一步:Android.mk文件增加LOCAL_LDLIBS += -llog

第二步:C代码中增加

#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__) LOGI("info\n");
LOGD("debug\n");

 * 在C中用反射调用JAVA中方法

public class MainActivity extends Activity {
static{
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} public void click(View v){
helloC();
} public native void helloC(); public void show(String message){
Builder builder = new Builder(this);
builder.setTitle("БъЬт");
builder.setMessage(message);
builder.show();
}
}

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_LDLIBS += -llog LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c include $(BUILD_SHARED_LIBRARY)

hello.c

#include <jni.h>
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) JNIEXPORT void JNICALL Java_com_itheima_ccalljava_MainActivity_helloC
(JNIEnv * env, jobject obj){ LOGD("hello!");
LOGI("hello!");
//jclass (*FindClass)(JNIEnv*, const char*);
jclass clazz = (*env)->FindClass(env, "com/itheima/ccalljava/MainActivity");
//jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodID = (*env)->GetMethodID(env, clazz, "show", "(Ljava/lang/String;)V");
//void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env, obj, methodID, (*env)->NewStringUTF(env, "是时候再黑一波小志了"));
}

JNI,NDK的更多相关文章

  1. JNI/NDK开发指南(开山篇)

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/41759643 相信很多做过Java或Android开发的朋友经常会接触到JNI方面的技术, ...

  2. JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程

    JNI/NDK Java调用C/C++前言  通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...

  3. (转)java 层调用Jni(Ndk) 持久化c c++ 对象

    对于Jni(Ndk) 很多人应该都有印象,Android的ndk接触到的机会相对会比较多,本例子以android平台为例,pc端的话就以简单的windows为例, 编码完用vs 或是 gcc进行编译成 ...

  4. android Jni NDK开发环境搭建及其简单实例的编写

    android  Jni  NDK开发环境搭建及其简单实例的编写 由于工作需要,需要采用开发想要的JNI,由于之前没有接触过安卓的开发,所以更加网上的帖子,学习了下.遇到了些问题,然后总结下学习过程中 ...

  5. Android JNI/NDK开发教程

    JNI/NDK开发指南:http://blog.csdn.net/xyang81/article/details/41759643

  6. JNI/NDK开发

    公司的新需求终于解决完了,离测试和发布还有段时间,第一次体验了下没需求没bug的感觉,真是舒爽~然后翻了翻有什么可以学的.无意翻到了Android后期发展的五大趋势.一.性能优化.二.高级UI.三.J ...

  7. Android JNI&NDK编程小结及建议

    前言 由于网上关于JNI/NDK相关的知识点介绍的比较零散而且不具备参照性,所以写了这篇JNI/NDK笔记,便于作为随时查阅的工具类型的文章,本文主要的介绍了在平时项目中常用的命令.JNI数据类型.签 ...

  8. AS2.2使用CMake方式进行JNI/NDK开发

    之前写过一篇比较水的文章Android手机控制电脑撸出HelloWorld 里面用到了JNI/NDK技术. 这篇文章给大家介绍下JNI/NDK开发.采用的是Android Studio2.2开发环境, ...

  9. 超简单的JNI——NDK开发教程

    不好意思各位,我按照网上一些教程进行JNI开发,折腾了半天也没成功,最后自己瞎搞搞定了,其实超简单的,网上的教程应该过时了,最新版的AS就包含了NDK编译的功能,完全不用手动javah,各种包名路径的 ...

  10. 【Android 系统开发】Android JNI/NDK (三) 之 JNIEnv 解析

    jni.h文件 : 了解 JNI 需要配合 jni.h 文件, jni.h 是 Google NDK 中的一个文件, 位置是 $/Android-ndk-r9d/platforms/android-1 ...

随机推荐

  1. JAVA本地方法详解,什么是JAVA本地方法?

    一. 什么是Native Method   简单地讲,一个Native Method就是一个java调用非java代码的接口.一个Native Method是这样一个java的方法:该方法的实现由非j ...

  2. ADF成长记1--认识ADF

    2014-07-08 近段时间由于公司项目需要,开始接触Oracle ADF.都说有事没事,上百度,但是对于IT技术而言,上百度还真是不一定好使,至于谷歌嘛,很不巧的进不去了.不过网上ADF的资料当真 ...

  3. HDU 1062 Text Reverse(水题,字符串处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1062 解题报告:注意一行的末尾可能是空格,还有记得getchar()吃回车符. #include< ...

  4. [BZOJ1101][POI2007]Zap

    [BZOJ1101][POI2007]Zap 试题描述 FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd ...

  5. 转:PCL+VS2010环境配置

    1.下载 http://www.pointclouds.org/downloads/windows.html出下载PCL完全安装包1.6.0 all-in-one-installer,我的电脑是32位 ...

  6. JSoup——用Java解析html网页内容

    当需要从网页上获取信息时,需要解析html页面.筛选指定标签,并获取其值是必不可少的操作,解析html页面这方面的利器,Python有BeautifulSoup,Java一直没有好的工具,之前的Htm ...

  7. 18个网站SEO建议

    第一位专家是Autotrader公司的搜索市场经理Dewi Nawasari,她认为SEO就是优化网站,以吸引你的目标客户的过程.她的建议如下: 1.创建良好的引导链接 要把用户的使用过程尽量的简化, ...

  8. VMware Snapshot 工作原理

    VMware中的快照是对VMDK在某个时间点的“拷贝”,这个“拷贝”并不是对VMDK文件的复制,而是保持磁盘文件和系统内存在该时间点的状态,以便在出现故障后虚拟机能够恢复到该时间点.如果对某个虚拟机创 ...

  9. Minimum Size Subarray Sum

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  10. poj 2709

    http://poj.org/problem?id=2709 题意:就是那个老师需要n瓶颜色的墨水,和1瓶颜色的灰色的墨水,但是灰色的墨水没得卖,只能由三种颜色相同的墨水混合而成,但是3瓶50ML的墨 ...