分类: Android平台

软硬件环境

  • ubuntu kylin 14.04
  • 红米note增强版
  • Android studio 0.8.6
  • ndk r10c

前言

本文的目标是在Android studio中进行NDK的开发。示例是在main activity中显示一个字符串,而字符串的内容是来自于一个C函数。归结于一句话:NDK是为了让上层的java应用能够调用底层的c/c++而设计的。马上进入主题。

创建工程

创建一个名为jniDemo的blank activity工程,activity名为MyActivity,在MyActivity类的最后声明一个方法,这个方法会在C函数中去实现,如下图所示,

jni部分

设置ndk路径,打开local.properties,增加

ndk.dir=/home/djstava/Workshop/Android/android-studio/ndk 

点击android studio左下角的Terminal

cd src/main

javah -d jni -classpath ~/Workshop/Android/android-studio/sdk/platforms/android-4.4.2/android.jar:../../build/intermediates/classes/debug/ com.example.djstava.jnidemo.MyActivity 

参数意义:

-d 输出目录,jni是gradle默认的路径
-classpath jar的路径,经常碰到的找不到activity的类的错误一般是由这个引起的
com.example.djstava.jnidemo.MyActivity 包名+activity

这条命令执行完毕后,会在src/main下生成jni目录,并产生头文件com_example_djstava_jnidemo_MyActivity.h,其内容为

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_example_djstava_jnidemo_MyActivity */ #ifndef _Included_com_example_djstava_jnidemo_MyActivity
#define _Included_com_example_djstava_jnidemo_MyActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_djstava_jnidemo_MyActivity_MODE_PRIVATE
#define com_example_djstava_jnidemo_MyActivity_MODE_PRIVATE 0L
#undef com_example_djstava_jnidemo_MyActivity_MODE_WORLD_READABLE
#define com_example_djstava_jnidemo_MyActivity_MODE_WORLD_READABLE 1L
#undef com_example_djstava_jnidemo_MyActivity_MODE_WORLD_WRITEABLE
#define com_example_djstava_jnidemo_MyActivity_MODE_WORLD_WRITEABLE 2L
#undef com_example_djstava_jnidemo_MyActivity_MODE_APPEND
#define com_example_djstava_jnidemo_MyActivity_MODE_APPEND 32768L
#undef com_example_djstava_jnidemo_MyActivity_MODE_MULTI_PROCESS
#define com_example_djstava_jnidemo_MyActivity_MODE_MULTI_PROCESS 4L
#undef com_example_djstava_jnidemo_MyActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_example_djstava_jnidemo_MyActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_example_djstava_jnidemo_MyActivity_BIND_AUTO_CREATE
#define com_example_djstava_jnidemo_MyActivity_BIND_AUTO_CREATE 1L
#undef com_example_djstava_jnidemo_MyActivity_BIND_DEBUG_UNBIND
#define com_example_djstava_jnidemo_MyActivity_BIND_DEBUG_UNBIND 2L
#undef com_example_djstava_jnidemo_MyActivity_BIND_NOT_FOREGROUND
#define com_example_djstava_jnidemo_MyActivity_BIND_NOT_FOREGROUND 4L
#undef com_example_djstava_jnidemo_MyActivity_BIND_ABOVE_CLIENT
#define com_example_djstava_jnidemo_MyActivity_BIND_ABOVE_CLIENT 8L
#undef com_example_djstava_jnidemo_MyActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_example_djstava_jnidemo_MyActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_example_djstava_jnidemo_MyActivity_BIND_WAIVE_PRIORITY
#define com_example_djstava_jnidemo_MyActivity_BIND_WAIVE_PRIORITY 32L
#undef com_example_djstava_jnidemo_MyActivity_BIND_IMPORTANT
#define com_example_djstava_jnidemo_MyActivity_BIND_IMPORTANT 64L
#undef com_example_djstava_jnidemo_MyActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_example_djstava_jnidemo_MyActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_example_djstava_jnidemo_MyActivity_CONTEXT_INCLUDE_CODE
#define com_example_djstava_jnidemo_MyActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_example_djstava_jnidemo_MyActivity_CONTEXT_IGNORE_SECURITY
#define com_example_djstava_jnidemo_MyActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_example_djstava_jnidemo_MyActivity_CONTEXT_RESTRICTED
#define com_example_djstava_jnidemo_MyActivity_CONTEXT_RESTRICTED 4L
#undef com_example_djstava_jnidemo_MyActivity_RESULT_CANCELED
#define com_example_djstava_jnidemo_MyActivity_RESULT_CANCELED 0L
#undef com_example_djstava_jnidemo_MyActivity_RESULT_OK
#define com_example_djstava_jnidemo_MyActivity_RESULT_OK -1L
#undef com_example_djstava_jnidemo_MyActivity_RESULT_FIRST_USER
#define com_example_djstava_jnidemo_MyActivity_RESULT_FIRST_USER 1L
#undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DISABLE
#define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DIALER
#define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DIALER 1L
#undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SHORTCUT
#define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
/*
* Class: com_example_djstava_jnidemo_MyActivity
* Method: getStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_djstava_jnidemo_MyActivity_getStringFromJNI
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif

根据产生的头文件,在同级目录创建C源文件,内容如下

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_example_djstava_jnidemo_MyActivity */ /*
* Class: com_example_djstava_jnidemo_MyActivity
* Method: getStringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_djstava_jnidemo_MyActivity_getStringFromJNI
(JNIEnv *env, jobject obj)
{
return (*env)->NewStringUTF(env,"Hello android from jni!");
}

gradle配置

打开build.gradle,在defaultConfig设置项内添加

ndk {
moduleName "jniLib" //这是模块名称,在加载时会被用到
}

在defaultConfig设置项后面添加

flavorGroups "abi"

productFlavors {
x86 {
ndk {
abiFilter "x86"
}
}
arm {
ndk {
abiFilter "armeabi-v7a"
}
}
mips {
ndk {
abiFilter "mips"
}
}
}

在MyActivity中加载jni模块,如下图所示,要去掉前缀lib和后缀.so

修改activity_my.xml

添加textView的id

android:id="@+id/jni_text" 

测试

不出意外的话,你的app的textView上会出现"Hello android from jni!"。生成的库位于app/build/intermediates/ndk/arm/debug/lib/armeabi-v7a/libjniLib.so,Makefile文件位于/home/djstava/AndroidstudioProjects/jniDemo/app/build/intermediates/ndk/arm/debug/Android.mk,apk文件位于/home/djstava/AndroidstudioProjects/jniDemo/app/build/outputs/apk,当然这些文件的生成都是在studio里做的,对用户是透明的。

参考资料

1、https://developer.android.com/tools/sdk/ndk/index.html
2、https://www.youtube.com/watch?v=okLKfxfbz40
3、http://www.shaneenishry.com/blog/2014/08/17/ndk-with-android-studio/
4、https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio
5、https://www.youtube.com/watch?v=e54f6dt9OZo&feature=youtube_gdata

在Android studio中进行NDK开发的更多相关文章

  1. 如何在Android Studio中指定NDK位置?

    如何在Android Studio中指定NDK位置? 问题描述 NDK已经手工下载解包在本地: D:\Portable\android-ndk-r13b 每次创建支持C++项目时,都提示NDK没配置, ...

  2. Android Studio 中关于NDK编译及jni header生成的问题

    之前由于工作原因使用grails这个基于groovy的框架做项目,对groovy感觉很好. 基于groovy的gradle构建系统对我而言自然也是好的没得说. Android Studio 正式版出来 ...

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

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

  4. Android Studio 2.2 NDK开发环境搭建

    转载请标明出处:http://blog.csdn.net/shensky711/article/details/52763192 本文出自: [HansChen的博客] Android应用程序使用ND ...

  5. 如何在android studio中cordova的混合开发

    基于Android Studio 中Cordova的开发 cordova简介 Cordova的前身是PhoneGap 官网: (http://cordova.io) Cordova应是运行在客户端本地 ...

  6. 关于Android Studio中使用jni进行opencv配置开发环境的要素秘诀

    使用jni进行opencv开发可以快速地将PC端的opencv代码移植到手机上,但是如何在android studio下进行配置,网上几乎找不到教程,大多都是eclipse下使用mk文件的方法,找不到 ...

  7. .Net程序员之不学Java做安卓开发:Android Studio中的即时调试窗口

    对学.Net的人来说,JAVA开发是一场噩梦. .net中的即时窗口,调试时直接在里面写代码,对程序中的各种方法/属性进行调用,很方便. Android Studio中找了好久,参考如下网址,也有类似 ...

  8. 在android studio中集成javah, ndk-build进行JNI开发

    最近在搞一个android上控制LED灯闪烁的功能,用到了串口编程,搜索了一下,发现Google发布了一个demo,android-serialport-api.有现成的代码和APK,要想自己改JNI ...

  9. cordova开发插件,并在android studio中开发、调试

    之前用过cordova Lib包装H5页面,自己写插件,但做法是野路子,不符合cordova插件的开发思路,这次项目又需要包装H5页面,同时需要自定义插件.所以又折腾了一次cordova自定义插件. ...

随机推荐

  1. 如何理解CSS中的浮动 :其实他就像乘坐扶梯一样

    只要你用过自动扶梯,你就能很快的理解CSS中的浮动(Float). 你肯定遇到过这样的情况:       做好了,你想用CSS浮动来调整元素间的位置关系. 在写完代码之后,你发现浮动元素没出现在你设想 ...

  2. ubuntu 14.04 32位库

    如果是ubuntu 14.04,则请先执行: 方法1: sudo gedit /etc/apt/sources.list 然后在最后添加上: deb http://archive.ubuntu.com ...

  3. epoll详解

    转自:http://blog.chinaunix.net/uid-24517549-id-4051156.html 什么是epoll epoll是什么?按照man手册的说法:是为处理大批量句柄而作了改 ...

  4. javascript动画效果之透明度

    在css中的filter对应老版本的ie浏览器,opacity对应的是其他浏览器 <!DOCTYPE html> <html> <head> <meta ch ...

  5. Python基础(四)-集合

    补充: 数据类型分类: 1.按照数据可变不可变: 可变:列表.字典 不可变:数字.字符串.元组 x={':1} print(id(x)) x.update({':2}) print(x) print( ...

  6. beginBackgroundTaskWithExpirationHandle

    [[UIApllication sharedApplication] beginBackgroundTaskWithExpirationHandle:^{}];这个方法在app进入后台时,可以做一些事 ...

  7. Xcode最最实用快捷键

      转发:http://www.open-open.com/lib/view/open1397988745593.html 关于与mac 通用的快捷键网上太多,就不说了,下面介绍一些大家不是很熟悉但是 ...

  8. IOS 导出ipa文件方法

    1.首先打开项目,Device选项栏选择“Generic iOS Device”.如下图所示: 2.选择屏幕上方的“product”并点击打开,选择“Archive”并点击打开,程序就会自动运行,运行 ...

  9. Flask -- 使用数据库(Sqlite3)、用户注册、登录注销、修改密码

    # 使用sqlite数据库 import sqlite3from contextlib import closing app.config.update( DATABASE = 'my.db', #相 ...

  10. javaWeb知识的回顾

    16年7月毕业,现在工作也有3个多月了.一直是在做一些增删改查,技术上没有太大的突破,自己总结下原因,还是原理理解的不够透彻,地基没打好就盖不成高楼. 在51cto上找到了佟刚老师的视频,快进游览一遍 ...