Android Studio NDK 学习之接受Java传入的字符串
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK。
用Android Studio新建一个工程叫Prompt,其目录结构如下:
├── Prompt.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 PROMPT_LOGGER_H_H
#define PROMPT_LOGGER_H_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 //PROMPT_LOGGER_H_H
2、接着创建prompt_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]))) #define JNIREG_CLASS "com/ndk/clarck/prompt/MainActivity" /**
* 返回字符串
*/
JNIEXPORT jstring JNICALL native_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
char outbuf[];
int len = (*env)->GetStringLength(env, prompt);
(*env)->GetStringUTFRegion(env, prompt, , len, outbuf); return (*env)->NewStringUTF(env, outbuf);
} /**
* Java和JNI函数绑定
*/
static JNINativeMethod method_table[] = {
{"getLine", "(Ljava/lang/String;)Ljava/lang/String;", (void*)native_getLine},
}; /**
* 注册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.prompt; import android.app.Activity;
import android.os.Bundle;
import android.util.Log; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String getLine = getLine("Type a line:");
Log.d("Test", "getLine: " + getLine);
} public native String getLine(String prompt); static {
System.loadLibrary("prompt_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 = 21
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "com.ndk.clarck.prompt"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 21
}
}
android.ndk {
moduleName = "prompt_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")
}
}
5、执行Build->Make Project,得到如下输出:
1:27:09 PM Executing tasks: [:app:compileAllDebugSources, :app:compileAllDebugAndroidTestSources]
1:27:10 PM Gradle build finished in 779ms
6、执行Run,即可运行项目了。
经验:
1、遇到Gradle sync failed: Cause: org.gradle.api.internal.ExtensibleDynamicObject这种错误的解决办法:
将Module下的build.gradle所有编译参数赋值都是采用xxx = xxx这种方式,而不能采用 xxx xxx这种赋值的方式
2、Android Studio Gradle编译确实比Eclipse中采用Android Makefile要方便很多。
Android Studio NDK 学习之接受Java传入的字符串的更多相关文章
- Android Studio NDK 学习之接受Java传入的Int数组
本博客是基于Android Studio 1.3 preview版本,且默认你已经安装了Android SDK, Android NDK. 用Android Studio新建一个工程叫AndroidJ ...
- Android NDK 学习之接受Java传入的字符串
本博客主要是在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传入的Int数组
本博客主要是在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下已经有自带 ...
随机推荐
- 关于堆排序和topK算法的PHP实现
问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n ...
- paip.myeclipse7 java webservice 最佳实践o228
paip.myeclipse7 java webservice 最佳实践o228 java的ws实现方案:jax-ws>>xfire ws的测试工具 webservice测试调用工具W ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- Windows环境下32位汇编语言程序设计(典藏版)
Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...
- Spring之@Configuration配置解析
1.简单的示例: @Configuration @EnableConfigurationProperties({DemoProperties.class}) public class DemoConf ...
- Android模拟器配置
// 检查连接设备,为了保证运行正常,只能留一个连接设备 adb devices
- python元类
第一个实例: # coding=utf8 # 手动创建,返回一个类对象 MyShinyClass = type('MyShinyClass', () ,{}) print(MyShinyClass) ...
- Log4cpp介绍及使用
Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能.使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流.内存字符串队列.文件.回滚文件.调试器.Wind ...
- 针对远程Git代码库使用SSH公匙
→ 运行Git Bash→ 创建SSH公匙和私匙ssh-keygen -t rsa→ 输入SSH公匙存放文件,选择使用默认的,按Enter→ 如果已经存在,提示是否重写,输入n,按Enter→ 打开C ...
- JavaMail发送邮件时判断发送结果1.5.x
经常有用户在平台乱注册帐号,系统得自动清理.现在要判断一下邮件是否正确少了很多垃圾注册用户了. 测试 http://sms.reyo.cn/user/register 感谢您的反溃信息!!! 程序代码 ...