我要重新拿回持之以恒徽章!!

老规矩,先说看能学会什么:ANDROID STUDIO下NDK的使用方法。JNI的基本使用方法,C语言调用JAVA的方法。

首先要下载NDK,如果你没有VPN可以来http://www.androiddevtools.cn/进行下载。下载后解压到任意目录。

其次,新建一个安卓项目。在MainActivity里添加一个Native方法。

  public native void showDialog();

这里不以HelloWorld举例了。来使用Java来调用C语言的方法,然后C语言的方法里再次调用java的方法来show一个dialog。这里在MainActivity写show()方法

   public void show(String message){
AlertDialog.Builder bulider = new AlertDialog.Builder(this);
bulider.setTitle("title");
bulider.setMessage(message);
bulider.show();
}

写完了之后 点击Builde里面的 MakeProject

然后打开终端 进入app/src/main/java目录,键入以下命令来编译头文件

cd app/src/main/java

javah -d ../jni com.wingsofts.jniii.MainActivity

之后再android studio下可以看到jni文件夹以及头文件,这个头文件的命名是 包名+类名

然后我们再来配置我们的gradle,编辑app目录下的build.gradle文件,在defaultConfig函数内加入以下函数。

 ndk {

            moduleName "JniTest"

            abiFilters "armeabi", "armeabi-v7a", "x86"

        }

然后再编辑local.properties。加入你的NDK路径(即刚解压的ndk)

sdk.dir=/Users/wing/android-sdk

ndk.dir=/Users/wing/android-ndk-r10e

此时,ndk的配置以及完成。我们将要用C语言实现函数的内容。

在jni文件夹下新建一个C文件。这里我起名叫做Hello。

具体怎么实现呢 首先看一下我们编译好的头文件是什么内容

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_wingsofts_jniii_MainActivity */ #ifndef _Included_com_wingsofts_jniii_MainActivity
#define _Included_com_wingsofts_jniii_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_wingsofts_jniii_MainActivity
* Method: showDialog
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_wingsofts_jniii_MainActivity_showDialog
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif

看到其中有一个函数 返回值为void 名称叫做 Java_com_wingsofts_jniii_MainActivity_showDialog,哇塞,这个函数名有点长。仔细观察,发现函数名是由包名加类名加函数名命名这也就解释了java和c方法是怎么对应的。然后看他的参数。(JNIEnv *,jobject),这是啥。。怎么看不懂呢。。 没关系,我们再来看看他include的一个头,jni.h

这里不全部贴出来了。只进行摘录

typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;

找到了以上语句。 原来这个JNIEnv 是一个JNINativieterface的指针,也就是说是一个环境。再来看

typedef void*           jobject;
typedef jobject jclass;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jobjectArray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jobject jthrowable;
typedef jobject jweak;

因为java的数据类型和C不一样,所以现在要用别名实现。这里是对应表。 可以看到这个函数第二个参数其实是jobject 也就是一个函数指针。

现在大概了解了。快来实现我的c函数吧。

#include "com_wingsofts_jniii_MainActivity.h"

JNIEXPORT void JNICALL Java_com_wingsofts_jniii_MainActivity_showDialog(JNIEnv* env,jobject jobj){
jclass clazz = (*env)->FindClass(env,"com/wingsofts/jniii/MainActivity");
jmethodID method = (*env)->GetMethodID(env,clazz,"show","(Ljava/lang/String;)V");
(*env)->CallVoidMethod(env,jobj,method,(*env)->NewStringUTF(env,"c调用java")); }

这里首先导入编译好的头文件。

然后实现方法名和头文件里的一样。 这个函数的目的是:调用java的方法,这里选择show一个dialog。所以需要用c语言来调用showDialog方法。于是要用到反射。跟java内的反射一样,先需要获取class然后放到类加载器中 在获得方法,才可以调用。

通过jni.h看到  jclass 就是java的 class    jmethodID就是java的Method 。

1.获取class

首先使用(*env)->的 findClass方法 传入环境变量 env 第二个参数是要寻找的类名  以路径的形式写。

2.获取method

获取到clazz之后 在获取其中的方法  仍然是使用(*env)->的GetMethodID方法。传入环境env Class clazz 然后是实例的方法名"show",最后一个是方法的签名。看起来样子很奇怪。其实也不奇怪,首先()里面的是参数的类型,因为java里传入的是一个String 所以这里是(Ljava/lang/String;) 后面跟着是返回值,因为是VOID所以这里是V。如果你不确定你写的方法对不对呢。还可以使用javap -s来查看方法的签名。

3.调用方法

这里因为返回值为void所以使用CallVoidMethod 如果是返回obj就是CallObjectMethod, 这些都可以从jni.h看到。前三个参数不做解释了,大家都明白。这里解释一下最后一个参数。这个参数就是show(String message)的参数。一看是String的花 如果直接写"c调用Java"是错误的。因为Java的字符串和C的字符串不是同一个类型。所以要调用NewStringUTF来转换一下。

好了这时我们的C语言文件遍实现好了。

快来运行一下试试。得到效果图

看起来也许不是很炫酷。但是想想这时由java调用C 在用C调用java来实现的。是不是立马变得高大上了?



Android Studio下使用NDK的流程的更多相关文章

  1. android studio下的NDK开发详解(一)

    源地址:http://www.voidcn.com/blog/chengkaizone/article/p-5761016.html 好记性不如烂笔头,开始坚持写博客,学一点记一点,只为了生活更好. ...

  2. Android studio 下的 NDK 配置方法和注意事项

    http://blog.csdn.net/u013598660/article/details/47341963

  3. Android studio 下 JNI 开发实例

    在AS中进行 NDK 开发之前,我们先来简单的介绍几个大家都容易搞懵的概念: 到底什么是JNI,什么是NDK? 何为“交叉编译”? 先看什么是 JNI?JNI 的全称就是 Java Native In ...

  4. Android studio 下JNI编程实例并生成so库

    Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...

  5. 在Android studio中进行NDK开发

     在Android studio中进行NDK开发  分类: Android平台 软硬件环境 ubuntu kylin 14.04 红米note增强版 Android studio 0.8.6 ndk ...

  6. Android Studio下jni应用

    最近在将一个小应用从eclipse开发迁移到android studio,程序中有native代码实现,在eclipse是靠Android.mk这么个mk文件来组织编译的,但到android stud ...

  7. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  8. Android Studio下打jar包

    在我们使用Eclipse时,我们常常使用的第三方类库文件大多都是jar包形式,用起来很方便.但是jar包只能打包class文件,对于Android UI类库而言,我们常常需要打包资源文件,对于界面不多 ...

  9. Android Studio下导出jar包和aar包

    Android Studio下导出jar包和aar包 jar包和aar包的区别 步骤 1. 创建Android工程 创建工程比较简单,不错复述 2. 创建一个Library(Module) 创建了一个 ...

随机推荐

  1. JSP基础概要

    [版权申明:本文系作者原创,转载请注明出处] 文章出处:http://blog.csdn.net/sdksdk0/article/details/51925232 作者:朱培 ID:sdksdk0 一 ...

  2. uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试

    今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...

  3. TCP协议的性能评测工具 — Tcpdive开源啦

    Github地址:https://github.com/fastos/tcpdive 为什么要开发Tcpdive 在过去的几年里,随着移动互联网的飞速发展,整个基础网络已经发生了翻天覆地的变化. 用户 ...

  4. 根据ccid取得账户,更改某段值再创建账户,返回新的ccid

    CREATE OR REPLACE PACKAGE cux_cuxaprebate_utl IS * =============================================== * ...

  5. Java基本语法-----java进制的转换

    进制: 进制是一种记数方式 ,可以用有限的数字符号代表所有的数值.由特定的数值组成. 1整型的表现形式 1.十进制: 都是以0-9这九个数字组成,不能以0开头. 2.二进制: 由0和1两个数字组成. ...

  6. Swift中声明协议中的class关键字的作用

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近在Cocos2D编程for Swift中看到以下一个代码片 ...

  7. 从操作系统内核看Java非阻塞IO事件检测

    非阻塞服务器模型最重要的一个特点是,在调用读取或写入接口后立即返回,而不会进入阻塞状态.在探讨单线程非阻塞IO模型前必须要先了解非阻塞情况下Socket事件的检测机制,因为对于非阻塞模式最重要的事情是 ...

  8. 插件开发之360 DroidPlugin源码分析(四)Activity预注册占坑

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52258434 在了解系统的activity,service,broa ...

  9. androidpn-server笔记及BUG修改

    上篇讲了androidpn的client端,这篇该讲一下我使用androidpn-server端的笔记了. 这里我使用的androidpn是tomcat版的,由不知哪位大神移植并修复了部分bug的版本 ...

  10. 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137 转载请著名出处 本博客相关文档下载 :  -- AR ...