android studio 下如何配置JNI环境
来源:互联网 发布:妮维雅 爽肤水 知乎 编辑:程序博客网 时间:2024/06/14 16:58
android stuido 下如何配置JNI环境
版本:Android stuido 2.2 windows 10操作系统
网上很多都是基于早期的eclipse环境配置的,studio的很少。以下是我亲测可用的一个详细过程。
安装配置NDK
一般如果你是第一次做jni的开发,studio的环境应该是没有ndk的,需要安装。在tools-android-sdk manager,进入sdk-tools选项,然后选中NDK进行安装。
默认安装在了
C:\android\sdk\android-sdk-windows\ndk-bundle
然后配置下环境变量:
新增NDK_ROOT,value为:
C:\android\sdk\android-sdk-windows\ndk-bundle
然后在path中增加%NDK_ROOT%
编写测试工程
新建一个工程,名为ssl_socket,package的全路径是com.example.pony.ssl_socket(很重要,后面会用到)。
我的MainActivity.java源码如下:
package com.example.pony.ssl_socket;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; //声明native方法 public native String getStringFromNative();// static表示在系统第一次加载类的时候,先执行这一段代码,在这里表示加载动态库libHelloWorldJni.so文件 static { Log.i(TAG, "loadLibrary"); System.loadLibrary("helloNDK"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "onCreate"); Log.i(TAG, getStringFromNative()); }}
public native String getStringFromNative();
这一行是声明一个native方法,也是我们一会在.c文件中要实现的方法。
System.loadLibrary(“helloNDK”);
这是让类启动时,加载名为helloNDK的模块,这是我们的jni模块名,这个名字和后面ndk编译时指定的名字一致。
编辑gradle.properties文件,增加:
android.useDeprecatedNdk=true
编辑app下的build.gradle,增加:
ndk { moduleName "helloNDK" // <-- This is the name of my C++ module! abiFilters "armeabi", "armeabi-v7a", "x86"// cFlags "-DANDROID_NDK -D_DEBUG DNULL=0" // Define some macros// ldLib编辑呢编辑s "EGL", "GLESv3", "dl", "log" // Link with these // stl "stlport_shared" // Use shared stlport library }
完整如下:
apply plugin: 'com.android.application'android { compileSdkVersion 24 buildToolsVersion "24.0.0" defaultConfig { applicationId "com.example.pony.ssl_socket" minSdkVersion 16 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk { moduleName "helloNDK" // <-- This is the name of my C++ module! abiFilters "armeabi", "armeabi-v7a", "x86"// cFlags "-DANDROID_NDK -D_DEBUG DNULL=0" // Define some macros// ldLib编辑呢编辑s "EGL", "GLESv3", "dl", "log" // Link with these libraries!,makefile里链接的库// stl "stlport_shared" // Use shared stlport library } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.0.0' compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha4' testCompile 'junit:junit:4.12'}
abiFilters是指明支持那些目标平台(ABI)。在Android系统上,每一个CPU架构对应一个ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64等。如果不加abiFilters这个选项,会生成所有abi平台的so文件。
build-make project,编译一下。这里可能会有疑问,上面的代码应该会报错呀,模块和方法明明都没有! 其实可以编译过的,你可以试下。
编译完后,会生成class文件。我的路径是:
d:\study\android\projects\SSL_Socket\app\build\intermediates\classes\debug\com\example\pony\ssl_socket\
其中com\example\pony\ssl_socket\是包名对应的路径。
打开studio的terminal,进入工程下的src/main目录下。然后执行:
javah -d jni -classpath C:\android\sdk\android-sdk-windows\platforms\android-24\android.jar;C:\android\sdk\android-sdk-windows\extras\android\support\v7\appcompat\libs\android-support-v7-appcompat.jar;C:\android\sdk\android-sdk-windows\extras\android\support\v4\android-support-v4.jar;..\..\build\intermediates\classes\debug com.example.pony.ssl_socket.MainActivity
命令有点长,拆开了分析:
javah是生成头文件需要的工具,-d jni表示在工程下生成jni目录,紧接着,
C:\android\sdk\android-sdk-windows\platforms\android-24\android.jar
指明android.jar路径。根据你自己的电脑相应修改。C:\android\sdk\android-sdk-windows\extras\android\support\v7\appcompat\libs\android-support-v7-appcompat.jar;
指明依赖的v7库,这个是因为你的类继承了AppCompatActivity。同理指明v4库,
C:\android\sdk\android-sdk-windows\extras\android\support\v4\android-support-v4.jar
如果不指明这些库,会下面这样的错误:
路径都根据自己的电脑相应修改。
命令运行成功后,会生成jni目录和一个头文件。
头文件的源码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_pony_ssl_socket_MainActivity */#ifndef _Included_com_example_pony_ssl_socket_MainActivity#define _Included_com_example_pony_ssl_socket_MainActivity#ifdef __cplusplusextern "C" {#endif#undef com_example_pony_ssl_socket_MainActivity_BIND_ABOVE_CLIENT#define com_example_pony_ssl_socket_MainActivity_BIND_ABOVE_CLIENT 8L#undef com_example_pony_ssl_socket_MainActivity_BIND_ADJUST_WITH_ACTIVITY#define com_example_pony_ssl_socket_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L#undef com_example_pony_ssl_socket_MainActivity_BIND_ALLOW_OOM_MANAGEMENT#define com_example_pony_ssl_socket_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L#undef com_example_pony_ssl_socket_MainActivity_BIND_AUTO_CREATE#define com_example_pony_ssl_socket_MainActivity_BIND_AUTO_CREATE 1L#undef com_example_pony_ssl_socket_MainActivity_BIND_DEBUG_UNBIND#define com_example_pony_ssl_socket_MainActivity_BIND_DEBUG_UNBIND 2L#undef com_example_pony_ssl_socket_MainActivity_BIND_EXTERNAL_SERVICE#define com_example_pony_ssl_socket_MainActivity_BIND_EXTERNAL_SERVICE -2147483648L#undef com_example_pony_ssl_socket_MainActivity_BIND_IMPORTANT#define com_example_pony_ssl_socket_MainActivity_BIND_IMPORTANT 64L#undef com_example_pony_ssl_socket_MainActivity_BIND_NOT_FOREGROUND#define com_example_pony_ssl_socket_MainActivity_BIND_NOT_FOREGROUND 4L#undef com_example_pony_ssl_socket_MainActivity_BIND_WAIVE_PRIORITY#define com_example_pony_ssl_socket_MainActivity_BIND_WAIVE_PRIORITY 32L#undef com_example_pony_ssl_socket_MainActivity_CONTEXT_IGNORE_SECURITY#define com_example_pony_ssl_socket_MainActivity_CONTEXT_IGNORE_SECURITY 2L#undef com_example_pony_ssl_socket_MainActivity_CONTEXT_INCLUDE_CODE#define com_example_pony_ssl_socket_MainActivity_CONTEXT_INCLUDE_CODE 1L#undef com_example_pony_ssl_socket_MainActivity_CONTEXT_RESTRICTED#define com_example_pony_ssl_socket_MainActivity_CONTEXT_RESTRICTED 4L#undef com_example_pony_ssl_socket_MainActivity_MODE_APPEND#define com_example_pony_ssl_socket_MainActivity_MODE_APPEND 32768L#undef com_example_pony_ssl_socket_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING#define com_example_pony_ssl_socket_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L#undef com_example_pony_ssl_socket_MainActivity_MODE_MULTI_PROCESS#define com_example_pony_ssl_socket_MainActivity_MODE_MULTI_PROCESS 4L#undef com_example_pony_ssl_socket_MainActivity_MODE_NO_LOCALIZED_COLLATORS#define com_example_pony_ssl_socket_MainActivity_MODE_NO_LOCALIZED_COLLATORS 16L#undef com_example_pony_ssl_socket_MainActivity_MODE_PRIVATE#define com_example_pony_ssl_socket_MainActivity_MODE_PRIVATE 0L#undef com_example_pony_ssl_socket_MainActivity_MODE_WORLD_READABLE#define com_example_pony_ssl_socket_MainActivity_MODE_WORLD_READABLE 1L#undef com_example_pony_ssl_socket_MainActivity_MODE_WORLD_WRITEABLE#define com_example_pony_ssl_socket_MainActivity_MODE_WORLD_WRITEABLE 2L#undef com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_DIALER#define com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_DIALER 1L#undef com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_DISABLE#define com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_DISABLE 0L#undef com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL#define com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L#undef com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL#define com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L#undef com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SHORTCUT#define com_example_pony_ssl_socket_MainActivity_DEFAULT_KEYS_SHORTCUT 2L#undef com_example_pony_ssl_socket_MainActivity_RESULT_CANCELED#define com_example_pony_ssl_socket_MainActivity_RESULT_CANCELED 0L#undef com_example_pony_ssl_socket_MainActivity_RESULT_FIRST_USER#define com_example_pony_ssl_socket_MainActivity_RESULT_FIRST_USER 1L#undef com_example_pony_ssl_socket_MainActivity_RESULT_OK#define com_example_pony_ssl_socket_MainActivity_RESULT_OK -1L#undef com_example_pony_ssl_socket_MainActivity_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS#define com_example_pony_ssl_socket_MainActivity_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS 65534L#undef com_example_pony_ssl_socket_MainActivity_HONEYCOMB#define com_example_pony_ssl_socket_MainActivity_HONEYCOMB 11L#undef com_example_pony_ssl_socket_MainActivity_MSG_REALLY_STOPPED#define com_example_pony_ssl_socket_MainActivity_MSG_REALLY_STOPPED 1L#undef com_example_pony_ssl_socket_MainActivity_MSG_RESUME_PENDING#define com_example_pony_ssl_socket_MainActivity_MSG_RESUME_PENDING 2L/* * Class: com_example_pony_ssl_socket_MainActivity * Method: getStringFromNative * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_pony_ssl_1socket_MainActivity_getStringFromNative (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
重点是Java_com_example_pony_ssl_1socket_MainActivity_getStringFromNative这个方法的声明。它的规则是
Java_ + 类的全限定名,用下划线进行分隔 + 方法名,
这样jvm运行的时候根据这个命名规则去找到对应的native方法。
然后在jni目录新建一个jni.c文件(名字随便取),源码如下:
#include <jni.h>/* Header for class com_example_pony_ssl_socket_MainActivity */#ifndef _Included_com_example_pony_ssl_socket_MainActivity#define _Included_com_example_pony_ssl_socket_MainActivity#ifdef __cplusplusextern "C" {#endifJNIEXPORT jstring JNICALL Java_com_example_pony_ssl_1socket_MainActivity_getStringFromNative (JNIEnv *env, jobject jobj){ return (*env)->NewStringUTF(env,"Hello From JNI!");}#ifdef __cplusplus}#endif#endif
所有的本地方法的第一个参数都是指向JNIEnv结构的。这个结构是用来调用JNI函数的。
编辑运行,可以在输出窗口看到:
Hello From JNI!
同时,c文件也生成了.so文件:
- android studio 下如何配置JNI环境
- Android Studio如何配置JNI环境
- android studio JNI环境配置
- Android Studio Jni 环境配置
- Android Studio Jni环境配置 - 记录
- Android Studio使用jni环境配置
- Android Studio NDK JNI编译环境 配置
- 【android ndk】macos环境下Android Studio中利用gradle编译jni模块及配置
- 【android ndk】macos环境下Android Studio中利用gradle编译jni模块及配置
- Android Studio JNI编程以及NDK环境配置
- Android Studio 配置JNI和NDK开发环境
- Android Studio利用Gradle配置NDK-JNI开发环境
- Android Studio JNI开发的环境配置 NDK
- Android Studio NDK环境配置及JNI使用方法
- android studio 配置NDK环境进行JNI开发
- Android Studio NDK环境配置与JNI简单的例子
- Mac环境下使用android studio jni基础
- android studio 2.0下 jni开发环境的搭建
- (转)专项:Android 内存泄露实践分析
- Linux 平台下Libusb & ccid & pcsc-lite & OpenSC 通用安装步骤
- Shell programming
- 学习Android路上的一些感慨和总结,慢慢来,比较快!
- 尽量使用安全的转换方式qobject_cast,少用强制转换
- android studio 下如何配置JNI环境
- Java强引用、软引用、弱引用、虚引用详解
- Linux基础学习(一)
- cocos2d -x 打包设置横屏和竖屏
- xcoj1009-密码
- NOIP2013提高组解析
- 软考——编译原理中的文法以及自动机
- Spring-5 bean的作用范围---单例和原型
- Leetcode 55 Jump Game