现在用android studio开发studio进行NDK开发成熟吗

使用Android Studio 进行NDK开发和调试 - 简书
使用Android Studio 进行NDK开发和调试
尽管Android Studio已经越来越流行了,但很多人还是习惯于Eclipse或源码环境下开发JNI应用。个人认为使用Android Studio作NDK开发是必然趋势,所以本文将简单介绍如何在Android Studio上实现NDK开发。
JNI 是Java Native Inteface的缩写,是Java中定义的一种用于连接Java和C/C++接口的一种实现方式。
NDK 是 Native Developmentit的缩写,是Google在Android开发中提供的一套用于快速创建native工程的一个工具。使用这个工具可以很方便的编写和调试JNI的代码。
NDK可从或(个人网站)下载。
Gradle 是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置。
以往Android NDK开发需要在Eclipse或源码环境下,建立并配置Android.mk和Application.mk,且还要通过java命令生成.h头文件,才能编译生成so库。但在Android Studio中这些步骤都不需要,因为Gradle足够强大,只需配置Gradle即可编译生成so库。
gradle-experimental插件
在2015年5月的Google I/O大会上, Google宣布Android Studio开始支持NDK开发,通过和JetBrains的合作,将Clion整合进了Android Studio 1.3,并免费支持NDK C++开发。
同年7月,在Android Studio 1.3版本上添加了gradle-experimental插件,该插件支持NDK开发和调试,且带有代码不全和重构等高级功能。
CAVEAT: Note that this plugin is a preview of the plugin for feedback on performance and NDK integration.
The Gradle API for the new component model is not final, which means each plugin will only work with a specific version of Gradle.Additionally, the DSL may also change.
目前这个插件是预览插件,并不是正式的。意味着插件只能运行在特定的Gradle版本上。并且DSL(领域特定语言)也要改变。
使用Experimental插件进行NDK开发
使用Experimental插件的必要条件
1、Gradle-2.5或更高版本2、Android Studio 1.3 RC1或更高版本3、Android NDK r10e 或更高版本4、Build Tools 19.0.0 或更高版本
每个版本的experimental插件需要特定的Gradle版本
Plugin Version
Gradle Version
0.3.0-alpha3
0.6.0-alpha1
0.6.0-alpha5
0.7.0-alpha1
NDK开发步骤
1、新建一个Android标准工程
2、按F4打开工程配置
3、使用experimental插件需要对以下三个文件做修改:
./build.gradle
./app/build.gradle
./gradle/wrapper/gradle-wrapper.properties
./gradle/wrapper/gradle-wrapper.properties
将distributionUrl改用gradle-2.10版本
distributionUrl=https\\://services.gradle.org/distributions/gradle-2.10-all.zip
./build.gradle
使用com.android.tools.build:gradle-experimental代替 com.android.tools.build:gradle
buildscript {
repositories {
dependencies {
//classpath 'com.android.tools.build:gradle:2.0.0'
classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha4"
// NOTE: Do not place your applicati they belong
// in the individual module build.gradle files
./app/build.gradle
这部分改动比较大,修改及注释如下:
// 用com.android.model.application 代替 com.android.application
apply plugin: 'com.android.model.application'
// 将原来的配置用 model{}包起来
// 取值必须使用 “=” 形式
// 否则会报 “Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject” 错误
compileSdkVersion = 23
buildToolsVersion = '23.0.2'
defaultConfig {
// 取值必须使用 “=” 形式
applicationId = "com.connorlin.jnitest"
//这里要注意是 xxSdkVersion.apiLevel
// 否则会报 “Unable to load class com.android.build.gradle.managed.ProductFlavor_Impl”错误
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode =
versionName = "1.0"
// 配置NDK
// 生成so的名字,是必须的
moduleName ="JNITest"
toolchain = 'clang'
CFlags.add('-std=c99')
// 添加依赖库
ldLibs.addAll(['android','OpenSLES', 'log'])
// 生成不同abi体系的so库
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a',
'x86', 'x86_64',
'mips', 'mips64'])
buildTypes {
minifyEnabled = false
// 这里注意:使用proguardFiles.add()方法
proguardFiles.add(file('proguard-rules.txt'))
4、在Java文件(这里以JNIActivity为例)中添加代码
System.loadLibrary("JNITest");
public native String testJni();
此时,native方法标红,提示如下:
在testJni()方法上按快捷键Alt + Enter,出现如下提示
按回车,会自动在main目录下生成jni文件夹,内含JniDemo.c:
#include &jni.h&
JNIEXPORT jstring JNICALL
Java_com_connorlin_jnitest_MainActivity_testJni(JNIEnv *env, jobject instance) {
return (*env)-&NewStringUTF(env, "returnValue");
你会发现,Android Studio已经为我们自动生成JNI方法了,你只需要再写实现就可以了。
至此,最简单的NDK开发配置完毕。
其他配置,请参考,Demo可以参考
换种方式进行NDK开发
既然预览版com.android.tools.build:gradle-experimental支持NDK,那么正式版com.android.tools.build:gradle 是否也可以实现NDK开发呢?
经过实验,答案是可以的!
1、新建一个Android标准工程,并在工程设置中配置NDK路径。
2、打开 app level 的 build.gradle, 配置NDK
moduleName "NdkJniDemo"
//生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,可忽略
然后点击右上角Sync Now, 会有如下错误提示:
按提示,在 gradl.properties 文件里加上android.useDeprecatedNdk=true即可。
3、在Java文件(这里以JNIActivity为例)中添加代码
System.loadLibrary("JNITest");
public native String testJni();
接着在testJni()方法上按快捷键Alt + Enter并回车,
同样,会自动在main目录下生成jni文件夹,内含JniDemo.c:
#include &jni.h&
但是,你会发现并不会自动生成JNI方法,这是因为使用experimental插件才会自动生成代码。
那自动生成代码该如何实现呢?
方法依然是使用gradle-experimental插件,但是不同的是,在app level的build.gradle中添加com.android.tools.build:gradle-experimental依赖。
4、在./app/build.gradle中添加gradle-experimental依赖
dependencies {
compile 'com.android.tools.build:gradle-experimental:0.7.0'
再次在testJni()方法上按快捷键Alt + Enter并回车
#include &jni.h&
JNIEXPORT jstring JNICALL
Java_com_connorlin_jnitest_MainActivity_testJni(JNIEnv *env, jobject instance) {
return (*env)-&NewStringUTF(env, "returnValue");
你会发现成功自动生成JNI方法了。
这种方式有个副作用是 Run app 时可能会报错:
此时,只要将gradle-experimental依赖注释掉即可正常运行,同时会保持自动生成代码的功能,直到关闭工程。这样我们在需要自动生成代码的时候,将gradle-experimental依赖再次打开即可。
默认情况下是不支持NDK调试的,但要支持NDK调试也很简单,只要做些简单配置即可。
1、打开JNI调试
2、配置Android Native - Debugger
3、下载LLDB 2.0
首次底部会报错
点击 Fix,提示下载LLDB 2.0,照做,下载安装即可。
4、完成NDK调试配置,可以正常调试了。
That's all!中国领先的IT技术网站
51CTO旗下网站
Android NDK开发,没有你想象的那么难
为什么要用NDK:我们都知道,java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。顺带提一下:NDK并不能显著提升应用效率。
作者:kym僵尸来源:oschina| 15:32
DK:Native Development Kit原生开发工具
NDK能干什么:NDK使得在android中,java可以调用C函数库。
为什么要用NDK:我们都知道,java是半解释型语言,很容易被反汇编后拿到源代码文件,在开发一些重要协议时,我们为了安全起见,使用C语言来编写这些重要的部分,来增大系统的安全性。还有,在一些接近硬件环境下,相信大家都清楚C与java的优劣。顺带提一下:NDK并不能显著提升应用效率。why?我们都觉得C语言比起java来说效率要高出很多,一方面,随着jdk的不断更新,java的效率也随之提高;另一方面,即便使用C语言编码提高了应用效率,但是在java与C相互调用时平白又增大了开销。
对于这些问题,这里就不多说了,希望详细了解的,请各位自行搜索。
NDK开发,第一步,当然是搭建环境
下载你对应平台的开发工具
接着,我们需要实现linux环境 下载cygwin& & (对于64位的用户,可以直接下载我已经下载好的,百度的链接应该比在线安装快一些,正在上传到我的网盘,稍后将地址放在回复里面)
选择在线下载的朋友,建议选择下图的地址,(是国内的)
选择好下载源以后就是选择下载目录了。我们用鼠标点开组件列表中的&Devel&分支,在该分支下,有很多组件,
我们必须的是:binutils,gcc,gcc-mingw,gdb
选好这四个目录了以后,就是漫长的等待了,可以去吃顿饭差不多了。
下面该配环境变量了:NDK环境变量需要将NDK根目录(其实就是ndk-builder.cmd文件的目录)加入系统环境变量
cygwin环境变量需要将bin目录加入系统环境变量
例如我的路径是:C:\java\android-ndk-r7b 和 C:\java\cygwin\bin 这两个
配置好环境后就可以开始编码了
1、新建一个android工程
2、在工程目录下添加名为 jni 的文件夹(必须)
3、在jni文件夹下新建你的.c文件(我的叫Hello.c)
4、在jni文件夹下新建名字为Android.mk文件
.mk文件中加入
LOCAL_PATH&:=&$(call&my-dir)&&&&&include&$(CLEAR_VARS)&LOCAL_MODULE&&&&:=&Hello&&&&&&&&&LOCAL_SRC_FILES&:=&Hello.c&&&&&&&&&include&$(BUILD_SHARED_LIBRARY)&
现在可以开始写我们的C代码了,当然这里不能再去从main函数开始写,而是有固定的命名方式
如图,我的函数名为:Java_com_example_testndk_MainActivity_helloWorldFromC&&&& (Java_包名_类名_函数名)
呵呵,写C的朋友可能要抱怨了,我什么时候写过这么长的函数名了。没办法,这是jni的规范,以Java_开头,后跟java应用的包名加上类名,都是以下划线分割,最后才是跟我们的C函数名
至于参数形式以及返回值类型,我们可以去jdk目录下翻阅jni.h文件(我的jni文件目录:C:\java\jdk1.7.0_25\include\jni),有很多函数模板(不同于C++模板)
由于源码太多大家自己去查看吧,我就不贴图了
在jni.h文件的第104行这里可以看到我们返回的jstring本质上就是一个结构体指针,从C代码里面可以看到就是一个指向字符串的指针,在java里也就是一个数组。
好了,C代码讲解完毕,回到我们android工程。
从刚才的C代码函数名,大家应该就可以知道我的java类名了(这是必须的,因为要一一对应嘛)
需要注意的是图中红色方框中的静态代码块
学过java大家都知道,一个 类在初始化的时候最先执行的不是构造方法而是静态代码块,没错也就是这里之所以把System.loadLibrary()放到静态代码块的原因。从名字我们就可以猜到了,加载库(&Hello&)
还记得我们在Android.mk中声明的那个Hello吗,就是那里的名字
紧接着,看到第12行代码,回忆java知识了,用native修饰的方法,表示java的本地方法,也就是我们的C函数了。(其实这样的函数在 android
SDK)中并不少见,比如我们常用到的多媒体类MediaPlayer,大家可以去看看源码,这里我就不发了,里面有很多native方法,因为要调用音 频驱动嘛。
至此,NDK工程就结束了,来测试一下吧。首先编译我们的C代码。打开cmd,切换到工程目录下(工程目录?右键工程名,properties,如上图)输 入ndk-builder(当时的环境变量设置成功了吗?去看看安卓工程的libs文件夹里面是不是多出来了个libHello.so文件)
然后我们再运行我们的安卓工程吧。
最后,我再说一点自己的看法吧,首先就是C语言的基础,结构体指针一定要掌握的好,好好看看jni.h文件给出了哪些函数,其中还有支持C与java交互的函数,要想用好NDK,先用好JNI
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
聚焦热点关注关注热点
24H热文一周话题本月最赞
讲师:427129人学习过
讲师:30976人学习过
讲师:153419人学习过
精选博文论坛热帖下载排行
全书分为基础篇、高级篇和应用篇3个部分,共18章,有重点、分层次地讲解SQL Server 2005的基础知识、高级使用技巧和项目应用方法。第1~10...
订阅51CTO邮刊android-jni(4)
Kotlin(1)
android-ko(2)
安卓kotlin(6)
kotlin探究之旅(8)
前几次总结了一下关于C或C++的基础知识及其开发流程。之前也大部分都是基于Elipse的。今天我们用AndroidStudio来开启我们的第一个项目实战。
但是基于AndroidStudio方面,以后趋势都是AndroidStudio开发NDK的,我们也同样的以后要用ES进行开发NDK.
先看效果图:
Java代码中调用C代码
C代码调用Java代码中
AndroidStudio环境配置:
下载地址 :(需要翻墙,你懂得)
在File–&Project Structure配置其路径
添加 ndk 后你会在 local.properties 这个文件看到(路径取决于你 ndk 的位置):
在此处加上这句代码:android.useDeprecatedNdk=true好了,ndk 环境搭建完毕!
开发示例流程
1.编写native方法
public class NdkJniUtils {
System.loadLibrary("myJniApp");
System.loadLibrary("unstallApp");
public native String getCLanguageString();
public native void uninstallListener();
2.在src/main目录下创建jni文件夹
3.生成.h头文件
1.首先build或者是make project使项目生成.class文件
2.在Androidstudio下的Terminal窗口里生成.h头文件
3.javah 包名.类名
Javah .mycptojavanative.jni..myndk01.NdkJniUtils
4.将生成的.h头文件Copy到jni目录下面
3.编写C代码
在jni目录里右击项目,新建.C文件进行编写C代码
现将生成的h文件里的内容Copy到.c文件里面去
去除不关联的无用的内容
按照规范进行C代码代码的编写
最后C代码示例:
#include &jni.h&
JNIEXPORT jstring JNICALL Java_cold_yyh_com_myndk01_NdkJniUtils_getCLanguageString (JNIEnv * env, jobject obj){
return (*env)-&NewStringUTF(env,"你好,ndk,我来了");
4.编写Android.mk文件
网上有很多博文来并没有要求建立Android.mk文件
但是为了正确的编译C代码,防止编译出错,这里我建议最好创建Android.mk
之前在Eclipse中建议将jni.h文件copy到jni文件夹下面,这里androids是之内的,无需做此操作
5.配置相关的gradle
声明ndk标签
如果不声明ndk标签,项目默认会创建一个libapp.so的文件(存放目录app\build\intermediates\ndk)
// 声明创建so库的文件名,会自动添加lib前缀, 添加了前缀,不会自动添加
moduleName "serviceData"
//声明启用Android日志, 在c/c++的源文件中使用的#include &android/log.h& 日志将得到输出
ldLibs "log"//实现__android_log_print
// 声明创建指定cpu架构的so库, 不声明的话, 默认(gradle 1.5.0)会生成4中架构 多一种mips架构
// 具体cpu架构的区别请参考:
// for detailed abiFilter descriptions, refer to "Supported ABIs" @
// /ndk/guides/abis.html#sa
abiFilters "armeabi", "armeabi-v7a", "x86"
//指定Android.mk文件
externalNativeBuild{
path "src/main/jni/Android.mk"
//指定so文件路径
sourceSets.main {
// 1. 配置在根目录libs下可以加载第三方so库, (最好不要创建jniLibs, 在众多的开源库中可能会引起冲突,还没发现)
// 2. 运行时会自动将libs目录下的so库拷贝到指定目录
// 3. 如果自己创建的so不需要重新编译,可以将(app/build/intermediates/transforms)生成的so拷贝到这个目录
jni.srcDirs = []
// 如果是单个文件夹 可以直接这样如下配置
//jniLibs.srcDir
//设置目标的so存放路径
jniLibs.srcDir 'src/main/jniLibs'
6.生成.so文件
利用AndroidStudio进行生成.so文件
build APK 、Make Project 、make Project Model 或者是 Rebuild Project 都能生成.so文件
注意:之前有找不到.so文件的情况,
这里已经解决。
其实so文件是存在 (app/build/intermediates/transforms)目录下的
将生成的so文件Copy到jniLibs文件夹下。
注意这里要新建jnilibs。
这里你也可以用命令指定生成ndk-build.cmd
7.在Java代码中调用动态链接库(.so)
在相应的地方进行加载so文件
System.loadLibrary("myJniApp");
System.loadLibrary("unstallApp");
示例代码:
private Button
btn_onclick,btn_onclick2;
private TextView mTextV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) this.findViewById(R.id.test);
btn_onclick = (Button) this.findViewById(R.id.btn_onclick);
final NdkJniUtils jni = new NdkJniUtils();
btn_onclick.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mTextView.setText(jni.getCLanguageString());
findViewById(R.id.btn_onclick2).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
jni.uninstallListener();
mTextView.setText("监听SD卡状态,查log日志");
项目下载地址:
github相关下载连接:
AndroidStudio项目:
如果下载不了,也可以通过csdn下载
AndroidStudio项目:
之前基于Eclise相关所写的介个项目
运行我的第一个ndk项目
仿银行登录系统
NDK探究之旅:
### 相信自己,没有做不到的,只有想不到的
如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :
微信公众号:终端研发部
(欢迎关注学习和交流)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:281553次
积分:4523
积分:4523
排名:第6946名
原创:163篇
转载:16篇
评论:173条
(6)(8)(4)(4)(9)(15)(9)(10)(7)(7)(3)(4)(1)(1)(2)(1)(1)(2)(8)(4)(3)(2)(3)(5)(4)(12)(4)(4)(6)(15)(3)(12)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'&& Android 开发了一段时间,一方面 ,感觉不留下点什么。有点对不起自己,
另一方面,好记性不如烂笔头,为了往后可以回头来看看,就当做是笔记,便决定开始写博客。废话不多说 !
&今天想搞一搞 ndk 和jni& ,, 现在开始写一个简单的demo
&1. 创建一个新的工程
2. 创建一个新的类 JniText.java& 点击Build--Make Project& 后 && &选中工程 点击F4键 sdk location 中 Android ndk location 选择配置ndk 的路径&& &没有下载的可以到这下载:/tools/sdk/ndk/&&&& 保险起见 点击查看 local.properties 文件&& &ndk.dir=D\:\\ndk\\android-ndk-r10e&& &sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\sdk&& &ok so good 下一步&&& &&& 查看 项目目录下的 E:\text\YipJniDemo\app\build\intermediates\classes\debug 生成了class文件&& &接下来 点击底下的Terminal窗口 cd 到当前项目目录&& &E:\text\YipJniDemo&cd E:\text\YipJniDemo\app\build\intermediates\classes\debug&&&& && 使用javah 生成头文件&& &E:\text\YipJniDemo\app\build\intermediates\classes\debug&javah -jni com.yip.yipjnidemo.JniText&& &&& &在 E:\text\YipJniDemo\app\build\intermediates\classes\debug&& &下可以看到生成的 com_yip_yipjnidemo_JniText.h&&
1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include &jni.h&
3 /* Header for class com_yip_yipjnidemo_JniText */
5 #ifndef _Included_com_yip_yipjnidemo_JniText
6 #define _Included_com_yip_yipjnidemo_JniText
7 #ifdef __cplusplus
8 extern "C" {
com_yip_yipjnidemo_JniText
getCLangString
* Signature: ()Ljava/lang/S
15 JNIEXPORT jstring JNICALL Java_com_yip_yipjnidemo_JniText_getCLangString
(JNIEnv *, jobject);
18 #ifdef __cplusplus
&&& && &在项目的src 文件下的&& &创建jni文件夹 注意 (右键main - new - Folder - JniFolder )&& &将生成的文件 com_yip_yipjnidemo_JniText.h 剪切到jni文件夹下&&& 在jni 目录下创建一个com_yip_yipjnidemo_JniText.c 文件&&
1 #include "com_yip_yipjnidemo_JniText.h"
io_github_yanbober_ndkapplication_NdkJniUtils
getCLanguageString
* Signature: ()Ljava/lang/S
7 JNIEXPORT jstring JNICALL Java_com_yip_yipjnidemo_JniText_getCLangString(JNIEnv *env, jobject obj)
return (*env)-&NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
&下一步, 在app的build.gradle;&&&
1 defaultConfig下添加
moduleName "jnitext"
//生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86"
//输出指定三种abi体系结构下的so库。目前可有可无。
&& &&& &点击 make-project&& &生成& .so 库&&
&此时报了 Error:(13, 0) Error: NDK integration is deprecated in the current
plugin.& Consider trying the new experimental plugin.& For details, see
/tech-docs/new-build-system/gradle-experimental.&
Set "android.useDeprecatedNdk=true" in gradle.properties to continue
using the current NDK integration.&a href="openFile:E:\text\MyJniDemo\app\build.gradle"&Open File&/a&&& &没关系
&& &我们在 & 工程下的gradle.properties 添加属性&&&
android.useDeprecatedNdk=true
&& 此时 补全 .YipJniDemo下MainActivity的代码
1 package com.yip.
3 import android.app.A
4 import android.support.v7.app.AppCompatA
5 import android.os.B
6 import android.widget.TextV
8 public class MainActivity extends Activity {
private TextView txtV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtView= (TextView) findViewById(R.id.txt_jnitext);
JniText jniText=new JniText();
txtView.setText(jniText.getCLangString());
&& JniText:
1 package com.yip.
* Created by Administrator on .
6 public class JniText {
System.loadLibrary("jnitext");
//defaultConfig.ndk.moduleName
public native String getCLangString();
&& ps:& 生成的. so文件有些盆友找不到 。其实是在这里的。&&
demo地址:
  /yipjunjie/JniDemo.git
  http://download.csdn.net/detail/sinat_9409
阅读(...) 评论()

我要回帖

更多关于 android studio开发js 的文章

 

随机推荐