Android Jni 开发(Android studio)
来源:互联网 发布:一元云购正版源码 编辑:程序博客网 时间:2024/05/22 04:24
转自:http://www.07net01.com/program/2016/03/1392017.html
前言: 在写这篇博客前,找了很多关于Android jni 开发的教程,但大都是基于eclipse 中开发的,就算是找到了用Android studio开发的教程,也没有一个能正确成功的,当时就感觉真是莫名的恼火,不过还好,最后按照自己的理解试成功了,下面就来仔细说下过程,有点多,因为要把我自己遇到的坑说出来。
注意:因为使用的工具和SDK版本不同,过程可能就不同,我把我试验过的几种情况都会说下。
一、工具和SDK版本:Android studio1.51, SDK版本:23 (最新的6.0)
二、工具和SDK版本:Android studio1.51, SDK版本:21
在这两种情况之前你必须做好一件事:安装NDK。过程如下:
在setting 中appearance -> Android SDK -> SDK Tools -> Android NDk 打钩,然后点击apply -> OK. 如下图:
自动安装好DN卡之后,会在 local.properties 中有显示:如下图
到此ND就安装完成了,那么接下来就是关键时刻了,先来看看情况一的具体过程:
1. 新建一个工程,就是一个简单的空白工程,功能也没有
2. 定义native 接口 和 加载即将生成的库。就几行代码,代码如下:
package zhanghuan.cn.jnitest1;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { static { system.loadLibrary("JniTest"); } public native String getStringFromNative(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView)findViewById(R.id.text); textView.setText(getStringFromNative()); // 调用接口 }}
3. 写好接口之后接下来就是关键了,点击 Build -> Make Project, 如下图:
然后在底部的状态栏messages 中查看Build的情况,必须是0错误才行,如下图:
4. Build 成功之后,就在Terminal 命令行中开始生成.h 文件
命令为:
Javah -d jni -classpath D:\tools\android-sdk\platforms\android-23\android.jar;D:\MyProject\AndroidStudio\JniTest1\app\src\main\java zhanghuan.cn.jnitest1.MainActivity
就是这一步卡了我好久,之前找的教程每个的命令都是这样的:
javah -d jni -classpath D:\tools\android-sdk\platforms\android.jar;..\..\build\intermediates\classes\debug zhanghuan.cn.jnitest1.MainActivity
结果报错 “找不到android.support.v7.app.AppCompatActivity的类文件” 如下图:
回归正题,命令成功之后,在main 目录下回生成jni目录,然后还有一个.h 文件:如下图:
我贴下.h 文件的代码:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class zhanghuan_cn_jnitest1_MainActivity */#ifndef _Included_zhanghuan_cn_jnitest1_MainActivity#define _Included_zhanghuan_cn_jnitest1_MainActivity#ifdef __cplusplusextern "C" {#endif/* * Class: zhanghuan_cn_jnitest1_MainActivity * Method: getStringFromNative * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jnitest1_MainActivity_getStringFromNative (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif5. 复制.h 文件放在相同的目录下,改个名称(名字任意)为my.c , 代码如下:
#include "zhanghuan_cn_jnitest1_MainActivity.h"JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jnitest1_MainActivity_getStringFromNative (JNIEnv * env, jobject job) { return (*env)->NewStringUTF(env, "Hello form JNI!");}
但是这时你会发现有错误,NDK support is an experimental feature and all use cases are not yet supported, 如下图:
解决方法是在 gradle.properties 文件中加入一句代码:
android.useDeprecatedNdk=true
ndk{ moduleName "JniTest" abiFilters "armeabi", "armeabi-v7a", "x86" }我的build.gradle 文件代码如下:
apply plugin: 'com.android.application'android { compileSdkversion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "zhanghuan.cn.jnitest1" minSdkVersion 11 targetSdkVersion 23 versionCode 1 versionName "1.0" ndk{ moduleName "JniTest" abiFilters "armeabi", "armeabi-v7a", "x86" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }}dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.2.1'}
到此,基本步骤就全部完成了,然后就直接运行一下,看下效果,效果图如下:
成功完成!如果有兴趣可以看下下面的第二种情况。
好了,接下来我们就看看第二种情况:不使用V7。
1. 前面的几步步骤和第一种情况是一样的,到第4步的命令行开始有重要的差别, 我就直接跳到命令行那步了,命令如下:
javah -d jni -classpath D:\tools\android-sdk\platforms\android-21\android.jar;D:\MyProject\AndroidStudio\JinTest\app\build\intermediates\classes\debug zhanghuan.cn.jintest.MainActivity
注意如果出错要写绝对的地址,网上的教程都是什么”..\..\buidl\...“这种写法,但是我一次都没成功,折腾了很久都没成功,如果你成功了就请告诉我。
最后生成的.h 文件代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class zhanghuan_cn_jintest_MainActivity */#ifndef _Included_zhanghuan_cn_jintest_MainActivity#define _Included_zhanghuan_cn_jintest_MainActivity#ifdef __cplusplusextern "C" {#endif#undef zhanghuan_cn_jintest_MainActivity_BIND_ABOVE_CLIENT#define zhanghuan_cn_jintest_MainActivity_BIND_ABOVE_CLIENT 8L#undef zhanghuan_cn_jintest_MainActivity_BIND_ADJUST_WITH_ACTIVITY#define zhanghuan_cn_jintest_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L#undef zhanghuan_cn_jintest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT#define zhanghuan_cn_jintest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L#undef zhanghuan_cn_jintest_MainActivity_BIND_AUTO_CREATE#define zhanghuan_cn_jintest_MainActivity_BIND_AUTO_CREATE 1L#undef zhanghuan_cn_jintest_MainActivity_BIND_DEBUG_UNBIND#define zhanghuan_cn_jintest_MainActivity_BIND_DEBUG_UNBIND 2L#undef zhanghuan_cn_jintest_MainActivity_BIND_IMPORTANT#define zhanghuan_cn_jintest_MainActivity_BIND_IMPORTANT 64L#undef zhanghuan_cn_jintest_MainActivity_BIND_NOT_FOREGROUND#define zhanghuan_cn_jintest_MainActivity_BIND_NOT_FOREGROUND 4L#undef zhanghuan_cn_jintest_MainActivity_BIND_WAIVE_PRIORITY#define zhanghuan_cn_jintest_MainActivity_BIND_WAIVE_PRIORITY 32L#undef zhanghuan_cn_jintest_MainActivity_CONTEXT_IGNORE_SECURITY#define zhanghuan_cn_jintest_MainActivity_CONTEXT_IGNORE_SECURITY 2L#undef zhanghuan_cn_jintest_MainActivity_CONTEXT_INCLUDE_CODE#define zhanghuan_cn_jintest_MainActivity_CONTEXT_INCLUDE_CODE 1L#undef zhanghuan_cn_jintest_MainActivity_CONTEXT_RESTRICTED#define zhanghuan_cn_jintest_MainActivity_CONTEXT_RESTRICTED 4L#undef zhanghuan_cn_jintest_MainActivity_MODE_APPEND#define zhanghuan_cn_jintest_MainActivity_MODE_APPEND 32768L#undef zhanghuan_cn_jintest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING#define zhanghuan_cn_jintest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L#undef zhanghuan_cn_jintest_MainActivity_MODE_MULTI_PROCESS#define zhanghuan_cn_jintest_MainActivity_MODE_MULTI_PROCESS 4L#undef zhanghuan_cn_jintest_MainActivity_MODE_PRIVATE#define zhanghuan_cn_jintest_MainActivity_MODE_PRIVATE 0L#undef zhanghuan_cn_jintest_MainActivity_MODE_WORLD_READABLE#define zhanghuan_cn_jintest_MainActivity_MODE_WORLD_READABLE 1L#undef zhanghuan_cn_jintest_MainActivity_MODE_WORLD_WRITEABLE#define zhanghuan_cn_jintest_MainActivity_MODE_WORLD_WRITEABLE 2L#undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DIALER#define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DIALER 1L#undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DISABLE#define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_DISABLE 0L#undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL#define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L#undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL#define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L#undef zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SHORTCUT#define zhanghuan_cn_jintest_MainActivity_DEFAULT_KEYS_SHORTCUT 2L#undef zhanghuan_cn_jintest_MainActivity_RESULT_CANCELED#define zhanghuan_cn_jintest_MainActivity_RESULT_CANCELED 0L#undef zhanghuan_cn_jintest_MainActivity_RESULT_FIRST_USER#define zhanghuan_cn_jintest_MainActivity_RESULT_FIRST_USER 1L#undef zhanghuan_cn_jintest_MainActivity_RESULT_OK#define zhanghuan_cn_jintest_MainActivity_RESULT_OK -1L/* * Class: zhanghuan_cn_jintest_MainActivity * Method: getStringFromNative * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_zhanghuan_cn_jintest_MainActivity_getStringFromNative (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
当然了,你还可以用第一种情况中的命令,也是OK的,同时不加上-classpath 和 android.jar,只指定要编译的类文件和.h文件目录就可以,如下:
javah -d jni D:\MyProject\AndroidStudio\JinTest\app\build\intermediates\classes\debug zhanghuan.cn.jintest.MainActivity
-d jni 是指定.h 生成后放的位置,不要自己建也是可以的。
最后生成的.so 文件在 app\build\intermediates\ndk\debug\lib 下,如下图:
到此,全部的情况都已介绍完毕,当然了,如果你在做的时候有问题的话欢迎留言,我们大家一起讨论交流。
源码我放在了github上:
https://github.com/john123fd/AndroidJNI21
https://github.com/john123fd/AndroidJNIV7
- Android Studio开发JNI
- Android Studio JNI开发
- Android Studio jni开发
- Android Studio jni开发
- android studio Jni开发
- Android studio JNI开发
- Android Studio JNI开发
- Android Studio JNI开发
- android studio jni开发
- Android Studio Jni开发
- Android Jni 开发(Android studio)
- Android Jni 开发(Android studio)
- Android studio JNI(NDK) 开发
- Android Studio开发JNI工程
- Android Studio开发JNI工程
- Android Studio开发JNI工程
- Android Studio开发JNI工程
- Android Studio开发JNI工程
- 《Linux内核设计与实现》——第4章(进程调度)
- 杭电1032:The 3n + 1 problem
- Android中DialogFragment的使用
- UITextKit框架的学习(二)
- Leetcode Edit Distance
- Android Jni 开发(Android studio)
- 绘图: matplotlib核心剖析
- 保留浮点数的两位小数点
- matplotlib-绘制精美的图表
- HDU 1176 免费馅饼(动规)
- SGU 144 Meeting(水~)
- linux常用命令一
- animation使用范围比transition广
- 用Python做科学计算