Android Studio NDK 学习之接受Java传入的Int数组
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK。
用Android Studio新建一个工程叫AndroidJNI_IntArray,其目录结构如下:
├── AndroidJNI_IntArray.iml
├── app
│ ├── app.iml
│ ├── build
│ ├── build.gradle
│ ├── libs
│ ├── proguard-rules.pro
│ └── src
├── build
│ └── intermediates
├── build.gradle
├── gradle
│ └── wrapper
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
切换到android视图,可见如下目录:

第一步,编写JNI代码:
1、新建jni文件夹,在jni文件夹下创建logger.h,用来打印输出日志的,其内容如下:
#ifndef ANDROIDJNI_INTARRAY_LOGGER_H
#define ANDROIDJNI_INTARRAY_LOGGER_H #include <jni.h>
#include <android/log.h> /**
* 定义log标签
*/
#define TAG "jni_logger" /**
* 定义info信息
*/
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) /**
* 定义debug信息
*/
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) /**
* 定义error信息
*/
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) #endif //ANDROIDJNI_INTARRAY_LOGGER_H
2、接着创建intarray_jni.c主要用来注册绑定java函数和native函数,以及java函数在c中相应函数的具体实现, 内容如下:
#include "logger.h" #ifndef NULL
#define NULL ((void *) 0)
#endif /**
* 获取数组大小
*/
#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0]))) /**
* 指定要注册的类,对应完整的java类名
*/
#define JNIREG_CLASS "com/ndk/clarck/MainActivity" /**
* 返回数组中元素的和
*/
JNIEXPORT jint JNICALL native_sumArray(JNIEnv *env, jobject obj, jintArray arr) {
jint *carr;
jint i, sum = ;
carr = (*env)->GetIntArrayElements(env, arr, NULL);
if (carr == NULL) {
return ;
} for (i = ; i < ; i++) {
sum += carr[i];
}
(*env)->ReleaseIntArrayElements(env, arr, carr, );
return sum;
} /**
* Java和JNI函数绑定
*/
static JNINativeMethod method_table[] = {
{"sumArray", "([I)I", (void *)native_sumArray},
}; /**
* 注册native方法到java中
*/
static int registerNativeMethods(JNIEnv *env, const char* className,
JNINativeMethod* gMethods, int numMethods) {
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
} if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < ) {
return JNI_FALSE;
} return JNI_TRUE;
} /**
* 调用注册方法
*/
int register_ndk_load(JNIEnv *env) {
return registerNativeMethods(env, JNIREG_CLASS, method_table, NELEM(method_table));
} JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
jint result = -; if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) {
return result;
} register_ndk_load(env);
return JNI_VERSION_1_4;
}
3、java层调用如下:
package com.ndk.clarck; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); int arr[] = new int[10];
for (int i = 0; i < 10; i++) {
arr[i] = i;
}
int sum = sumArray(arr);
Log.d("Test", "sum: " + sum);
} public native int sumArray(int[] arr); static {
System.loadLibrary("intarray_jni");
}
}
第二步,配置如下环境,执行编译命令:
1、在local.properties配置SDK和NDK路径如下:
sdk.dir=xxxx
ndk.dir=xxx
2、打开gradle-wrapper.properties,将其配置修改为使用Gradle 2.5来编译(详情参考:http://www.cnblogs.com/tanlon/p/4731283.html):

#Mon Aug 17 20:34:50 HKT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip

3、配置Project下面的build.gradle,其内容如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
4、配置Module下面的build.gradle,其内容如下:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 22
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "com.ndk.clarck"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 21
}
}
android.ndk {
moduleName = "intarray_jni"
ldLibs += ["log"]
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.productFlavors {
create ("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create ("arm8") {
ndk.abiFilters += "arm64-v8a"
}
create ("x86-32") {
ndk.abiFilters += "x86"
}
// for detailed abiFilter descriptions, refer to "Supported ABIs" @
// https://developer.android.com/ndk/guides/abis.html#sa
// build one including all cpu architectures
create("all")
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
}
5、执行Build->Make Project,得到如下输出:
Information:Gradle tasks [:app:assembleAllDebug]
:app:copyArm64-v8aDebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createArm64-v8aDebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileArm64-v8aDebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkArm64-v8aDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsArm64-v8aDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:arm64-v8aDebugAllIntarray_jniSharedLibrary
:app:copyArmeabi-v7aDebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createArmeabi-v7aDebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileArmeabi-v7aDebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkArmeabi-v7aDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsArmeabi-v7aDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:armeabi-v7aDebugAllIntarray_jniSharedLibrary
:app:copyArmeabiDebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createArmeabiDebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileArmeabiDebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkArmeabiDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsArmeabiDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:armeabiDebugAllIntarray_jniSharedLibrary
:app:preBuild UP-TO-DATE
:app:preAllDebugBuild UP-TO-DATE
:app:checkAllDebugManifest
:app:preAllReleaseBuild UP-TO-DATE
:app:preArm7DebugBuild UP-TO-DATE
:app:preArm7ReleaseBuild UP-TO-DATE
:app:preArm8DebugBuild UP-TO-DATE
:app:preArm8ReleaseBuild UP-TO-DATE
:app:preX86-32DebugBuild UP-TO-DATE
:app:preX86-32ReleaseBuild UP-TO-DATE
:app:prepareComAndroidSupportAppcompatV72220Library UP-TO-DATE
:app:prepareComAndroidSupportSupportV42220Library UP-TO-DATE
:app:prepareAllDebugDependencies
:app:compileAllDebugAidl UP-TO-DATE
:app:compileAllDebugRenderscript UP-TO-DATE
:app:generateAllDebugBuildConfig UP-TO-DATE
:app:generateAllDebugAssets UP-TO-DATE
:app:mergeAllDebugAssets UP-TO-DATE
:app:generateAllDebugResValues UP-TO-DATE
:app:generateAllDebugResources UP-TO-DATE
:app:mergeAllDebugResources UP-TO-DATE
:app:processAllDebugManifest UP-TO-DATE
:app:processAllDebugResources UP-TO-DATE
:app:generateAllDebugSources UP-TO-DATE
:app:processAllDebugJavaRes UP-TO-DATE
:app:compileAllDebugJavaWithJavac
:app:copyMips64DebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createMips64DebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileMips64DebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkMips64DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsMips64DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:mips64DebugAllIntarray_jniSharedLibrary
:app:copyMipsDebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createMipsDebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileMipsDebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkMipsDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsMipsDebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:mipsDebugAllIntarray_jniSharedLibrary
:app:copyX86DebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createX86DebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileX86DebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkX86DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsX86DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:x86DebugAllIntarray_jniSharedLibrary
:app:copyX86_64DebugAllIntarray_jniSharedLibraryGdbServer UP-TO-DATE
:app:createX86_64DebugAllIntarray_jniSharedLibraryGdbsetup
:app:compileX86_64DebugAllIntarray_jniSharedLibraryIntarray_jniMainC UP-TO-DATE
:app:linkX86_64DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:stripSymbolsX86_64DebugAllIntarray_jniSharedLibrary UP-TO-DATE
:app:x86_64DebugAllIntarray_jniSharedLibrary
:app:compileAllDebugSources
:app:preDexAllDebug UP-TO-DATE
:app:dexAllDebug
:app:validateDebugSigning
:app:packageAllDebug
:app:zipalignAllDebug
:app:assembleAllDebug
Information:BUILD SUCCESSFUL
Information:Total time: 2.772 secs
Information:0 errors
Information:0 warnings
Information:See complete output in console
6、执行Run,即可运行项目了。
经验:
Error:Cause: com.android.build.gradle.managed.AndroidConfig Impl 原因:
defaultConfig 必须写成 defaultConfig.with
Android Studio NDK 学习之接受Java传入的Int数组的更多相关文章
- Android Studio NDK 学习之接受Java传入的字符串
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫Prompt,其 ...
- Android NDK 学习之接受Java传入的Int数组
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK 学习之接受Java传入Object数组
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK 学习之接受Java传入的字符串
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android Studio NDK开发-JNI调用Java方法
相对于NDK来说SDK里面有更多API可以调用,有时候我们在做NDK开发的时候,需要在JNI直接Java中的方法和变量,比如callback,系统信息等.... 如何在JNI中调用Java方法呢?就需 ...
- Android Studio NDK编程初探
继上一篇学习了如何使用NDK编译FFMPEG后,接下来就是要学习如何在Android Studio中使用了. 经过参考和一系列的摸索,记录下具体步骤. 创建C++ Support的Android St ...
- Android Studio NDK环境配置
本文参考:Android Studio NDK环境配置及JNI使用方法:http://blog.csdn.net/tongseng/article/details/53005123 并添加自己的实践: ...
- android的ndk学习(1)
android的ndk学习(1) 之前学了一段时间ndk,总认为要总结一下.ndk使得很方便地实现java和C与C++代码的相互沟通.合理地掌握使用ndk能够提高应用程序的运行效率.所以对于学习a ...
- 【Android】Android Studio NDK 开发
Android Studio NDK 开发 记录在Android Studio中NDK简单开发的步骤 用到的Android Studio版本为3.5. 配置NDK 下载NDK 一般在SDK下已经有自带 ...
随机推荐
- CSS Sticky Footer: 完美的CSS绝对底部
CSS的简单在于它易学,CSS的困难在于寻找更好的解决方案.在CSS的世界里,似乎没有完美这种说法.所以,现在介绍的CSS绝对底部,只是目前个人见过的方案中比较完美的吧. 先说我们为什么会使用到这个C ...
- Javascript中prototype属性的详解
原文链接:http://www.cnblogs.com/Uncle-Keith/p/5834289.html 在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象 ...
- iOS开发中使用CocoaPods来管理第三方的依赖程序
之前也碰到类似的问题,怎样去管理这些第三方的文件,虽然手动添加也不算麻烦. 写这篇文章主要参考了唐巧的博文,链接如下: http://blog.devtang.com/blog/2012/12/02/ ...
- Android中的IOC框架,完全注解方式就可以进行UI绑定和事件绑定
转载请注明出处:http://blog.csdn.net/blog_wang/article/details/38468547 相信很多使用过Afinal和Xutils的朋友会发现框架中自带View控 ...
- Android中Parcelable接口的使用
在做开发的过程中,序列化是非常常见的.比如要将对象保存本地磁盘或者在网络上传输等.实现序列化有两种方式,一种是实现Serializable接口,第二种是实现Parcelable. Serializab ...
- django关闭debug后,静态文件的处理
Django框架仅在开发模式下提供静态文件服务.当我开启DEBUG模式时,Django内置的服务器是提供静态文件的服务的,所以css等文件访问都没有问题,但是关闭DEBUG模式后,Django便不提供 ...
- Hadoop学习篇 2 初识 Hadoop
在一个全配置的集群上,运行Hadoop意味着在网络分布的不同服务器上运行一组守护进程 (daemons),这些守护进程或运行在单个服务器上,或运行与多个服务器上,他们包括: (1) NameNode( ...
- webService调用
1.wsimport 生成客户端 2.axis2 3.通过HttpClient调用webservice 4.使用xfire
- Gradle中ProGuard的配置
好久没有写博客了…元旦前赶紧写一篇吧… 这些日子琢磨了一下gradle.对比起maven确实在配置上灵活很多,对groovy的支持可以更容易的自定义任务. 由于最近的几个项目中都使用到了moco这个开 ...
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...