• Android Studio ndk-Jni开发详细


    http://www.open-open.com/lib/view/open1451917048573.html

    Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。
    由于Android的应用层的类都是以Java写的,这些Java类编译为Dex型式的Bytecode之后,必须靠Dalvik虚拟机(VM: Virtual Machine)来执行。VM在Android平台里,扮演很重要的角色。
    (多的咱不说了,介绍什么的 到处都有可以去搜一下)
    咱们先建一个NdkJniDemo的工程

    新建工程.png


    新建JniUtils类实现native方法

    public class JniUtils {    public static native String getStringFormC();
    }

    build.png


    然后clean project 再rebuild project 生成class文件,
    这时候打开如下图的文件夹看是否生成了classes文件夹,没有生成请重新来过。

    文件夹.png


    再打开Terminal输入指令
    cd app/build/intermediates/classes/debug
    然后再输入指令
    javah -jni com.wobiancao.ndkjnidemo.ndk.JniUtils
    注意 这里javah -jni后面跟的是JniUtils类的全路径,如果javah报不存在之类的,是你的java环境没有配置好。

    Paste_Image.png


    这时候打开classes/debug下面的文件发现多了一个文件
    com_wobiancao_ndkjnidemo_ndk_JniUtils.h
    然后在src/main下新建文件夹jni,把生成的.h文件复制或者剪切到jni文件夹下面去,新建一个c类随便取一个名字,添加代码如下

    //// Created by XY on 16/1/4.//#include "com_wobiancao_ndkjnidemo_ndk_JniUtils.h"/* 
    * Class:     Java_com_wobiancao_ndkjnidemo_ndk_JniUtils 
    * Method:    getStringFormC 
    * Signature: ()Ljava/lang/String; 
    */JNIEXPORT jstring JNICALL Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getStringFormC
            (JNIEnv *env, jobject obj){ 
       return (*env)->NewStringUTF(env,"这里是来自c的string");

    这里发现头文件#include <jni.h>报红色,是因为咱们还没有配置ndk环境,打开file->project structure
    选择你所下载的ndk环境路径,如果没有ndk这里有个地址大家可以去下载 一个安卓工具集合的网站:http://androiddevtools.cn/

    Paste_Image.png


    设置好了之后,发现头文件还是红色的,然后再build一下工程,就会有提示

    Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.

    按着提示做就行了 在gradle.properties文件末尾添加android.useDeprecatedNdk=true就ok啦
    然后在app文件下得build.gradle ->defaultConfig括号内添加如下代码

    ndk {    
       moduleName "NdkJniDemo"          //生成的so名字 
       abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,目前可有可无。}

    到了这一步重新build项目,发现已经没有变红了。接下来就是运用了,在JniUtils类里面添加如下代码

    static {    
       System.loadLibrary("NdkJniDemo");//之前在build.gradle里面设置的so名字,必须一致}

    然后简单调用就行了,MainActivity代码如下

    public class MainActivity extends AppCompatActivity { 
       TextView textView;    
    @Override    protected void onCreate(Bundle savedInstanceState) { 
           super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            textView = (TextView) findViewById(R.id.ndk_text);
            textView.setText(JniUtils.getStringFormC());
        }
    }

    运行结果如图

    运行图.png


    咱们打开app->intermediates-ndk-debug发现生成了三个文件夹,并且对应了之前我们在build.gradle配置的abiFilters
    大功告成。
    新建libs文件夹把这三个文件夹放进去

    Paste_Image.png


    然后删除咱们的jni文件试试,是否工程还能运用?
    ok 教程完毕
    最后出一个利用jni的Aes加密demo运行结果如图所示

    Aes加密.png


    项目地址:https://github.com/a12a15a05/NdkJniDemo
    谢谢star欢迎点赞=。=转载请注明来源

    来自: http://www.jianshu.com/p/d8cde65cb4f7

     

    Android Studio进行NDK开发笔记

    http://blog.csdn.net/enlangs/article/details/51881718

    方案一

    • AS自带的有NDK插件,但是会出现Deprecated错误。解决方法:按提示操作即可。
    • AS的NDK插件不需要编写Application.mk和Android.mk,所以自己编写的无效!!,关键是那插件功能太弱了(很多Android.mk的属性不能修改)。如果想用自己的mk文件,需要在app/build.gradle中打掉NDK的所有配置。

      android {
      compileSdkVersion 23
      buildToolsVersion "23.0.2"
      defaultConfig {
          applicationId "ckm.xxx.testndk"
          minSdkVersion 19
          targetSdkVersion 23
          versionCode 1
          versionName "1.0"
      // 如果要使用自己的Application.mk和Android.mk需要修改下面2处。
      // 修改1,直接打掉下面配置
      //        ndk{
      //            moduleName "test"
      //            abiFilters "armeabi","armeabi-v7a"
      //        }
      }
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
          }
      }
      //    sourceSets { main { jni.srcDirs = ['src/main/jni'] } }
      // 修改2,需要把jni.srcDirs设置为空。
      //    sourceSets {
      //        main {
      //            jni.srcDirs = []
      //        }
      //    }
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
    • 自动生成头文件,在extend tool中增加配置: 
      位置1
      参数内容:

    Program:C:Program FilesJavajdk1.8.0_25injavah.exe
    Parameters:-v -jni -d $ModuleFileDir$srcmainjni $FileClass$
    Working directory:$SourcepathEntry$
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    设置结果 
    具体设置
    - 设置ndk-build的extend tool

    Program:C:
    dk
    dk-build.cmd
    Parameters:NDK_PROJECT_PATH=$ModuleFileDir$/build/intermediates/ndk NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs NDK_APPLICATION_MK=$ModuleFileDir$/src/main/jni/Application.mk APP_BUILD_SCRIPT=$ModuleFileDir$/src/main/jni/Android.mk V=1
    Working directory:$SourcepathEntry$
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    最终结果:这里写图片描述

    疑惑:

    • 我不相信AS不支持mk文件(只能当做文本文件识别),肯定有地方设置,还为找到设置地方。

    注意:

    如果按照上面的方式使用自定义Android.mk那么AS将无法识别到native函数。

    方案二

    来源:http://stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio

    此方案主要是直接修改build.gradle

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 14
        buildToolsVersion "20.0.0"
    
        defaultConfig {
            applicationId "com.example.application"
            minSdkVersion 14
            targetSdkVersion 14
    
            ndk {
                moduleName "YourModuleName"
            }
        }
    
        sourceSets.main {
            jni.srcDirs = [] // This prevents the auto generation of Android.mk
            jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
        }
    
        task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
            def ndkDir = android.ndkDirectory
            commandLine "$ndkDir/ndk-build",
                    '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                    '-j', Runtime.runtime.availableProcessors(),
                    'all',
                    'NDK_DEBUG=1'
        }
    
        task cleanNative(type: Exec, description: 'Clean JNI object files') {
            def ndkDir = android.ndkDirectory
            commandLine "$ndkDir/ndk-build",
                    '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                    'clean'
        }
    
        clean.dependsOn 'cleanNative'
    
        tasks.withType(JavaCompile) {
            compileTask -> compileTask.dependsOn buildNative
        }
    }
    
    dependencies {
        compile 'com.android.support:support-v4:20.0.0'
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    参考:图片和extend tool设置都来自这位博主,非常感谢。

    参考(请同事写了段代码处理下):

    #!/bin/sh
    
    for arg in "$@"
    do
     if [[ $arg == NDK_PROJECT_PATH=* ]];then
      param1=`echo $arg | awk -F = '{printf $1}'`
     elif [[ $arg == APP_BUILD_SCRIPT=* ]];then
      param2=`echo $arg | awk -F = '{printf $2}'`
     else
      param="$param $arg"
     fi
    done
    
    #echo $param2
    param2=`echo $param2 | sed 's#build/intermediates/ndk/debug/Android.mk#src/main#g'`
    #echo $param2
    #echo ""
    
    if [[ -n "$param1" ]] && [[ -n "$param2" ]]
    then
      param1="$param1=$param2"
      param="$param1 $param"
    fi
    DIR="$(cd "$(dirname "$0")" && pwd)"
    $DIR/build/ndk-build $param
  • 相关阅读:
    CodePlus#4 最短路
    最大子矩阵问题———悬线法
    Luogu P3393 逃离僵尸岛
    SCOI2011 糖果
    关于页面的跳转添加参数(比如id啥的)
    npm 常用命令
    移动开发中的一些基本的思想,和需要注意的细节技巧之处
    Mock模拟后台数据接口--再也不用等后端的API啦
    普及知识
    移动端JD首页H5页面
  • 原文地址:https://www.cnblogs.com/jukan/p/6038277.html
Copyright © 2020-2023  润新知