Android Studio中使用NDK

编译环境

  • Win10 64bit 企业版
  • Android Studio 1.5
  • android-ndk-r10e

Here we go!

  1. 新建项目
    这里新建一个项目名为FFmpegDemo的项目(过程略)
    Android Studio中使用NDK_第1张图片

  2. 声明native方法
    MainActivity中声明native方法:

    public native String getStringFromNative();
    

    然后Build - Make Project
    之后可以在FFmpegDemo\app\build\intermediates\classes\debug\com\example\l1\ffmpegdemo下看到class中间文件

  3. 生成头文件(.h)
    在Android Studio的Terminal中进入项目main目录,并运行下面命令以生成头文件:

    javah -d jni -classpath E:\Android\AndroidStudioSDK\platforms\android-19\android.jar;‪‪
    E:\Android\AndroidStudioSDK\extras\android\support\v4\android-support-v4.jar;
    E:\Android\AndroidStudioSDK\extras\android\support\v7\appcompat\libs\android-support-v4.jar;
    E:\Android\AndroidStudioSDK\extras\android\support\v7\appcompat\libs\android-support-v7-appcompat.jar;
    

    Android Studio中使用NDK_第2张图片
    -d:表示新建目录
    -classpath:指定类路径
    我这边如果不指定类路径会出现错误:

    错误: 无法访问android.support.v7.app.AppCompatActivity 
    找不到android.support.v7.app.AppCompatActivity的类文件
    

    运行完命令后,将会多一个jni目录,并且里面有个头文件(.h)
    Android Studio中使用NDK_第3张图片

  4. 实现头文件中声明的方法
    在jni目录下新建一个.c文件,用以实现.h头文件中的声明方法。这里命名为main.c,并简单的返回字符串。

    #include "com_example_l1_ffmpegdemo_MainActivity.h"
    
    JNIEXPORT jstring JNICALL Java_com_example_l1_ffmpegdemo_MainActivity_getStringFromNative(JNIEnv *env, jobject obj)
    {
        return (*env)->NewStringUTF(env,"Hello JNI");
    }
    
  5. 配置NDK路径和指定动态库名称

    Android Studio中使用NDK_第4张图片
    local.properties增加NDK路径,文件变成:

    sdk.dir=E:\\Android\\AndroidStudioSDK
    ndk.dir=E:\\Android\\android-ndk-r10e
    

    此外,还要在gradle.properties文件中加入:

    android.useDeprecatedNdk=true
    

    否则会报错:

    Error:Execution failed for task ':app:compileDebugNdk'.
    > 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.
    

    点击Build - Make Project可以在FFmpegDemo\app\build\intermediates\ndk\debug\lib\armeabi下看到libapp.so文件,这是默认的动态库名称,我们可以在build.gradle(Module:app)文件里指定动态库名称:

    android {
        ...
        defaultConfig {
            ...
            ndk {
                moduleName "MyLib"  //指定生成动态库的名称
            }
        }
        ...
    }
    

    重新编译即可看到libapp.so变成了libMyLib.so
    Android Studio中使用NDK_第5张图片

  6. 使用native方法
    最后在MainActivity中增加动态库载入代码就可以调用native方法啦~

    public class MainActivity extends AppCompatActivity {
    
        //载入动态库
        static {
            System.loadLibrary("MyLib");
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TextView tv = (TextView) findViewById(R.id.my_tv);
            tv.setText(getStringFromNative());  //调用native方法
        }
    
        //声明native方法
        public native String getStringFromNative();
    }
    

    编译运行就可以在屏幕上看到Hello JNI啦~~
    Android Studio中使用NDK_第6张图片

C语言中输出Logcat?没问题!

要想在C语言实现代码中输出Logcat信息,其实很简单!!
首先,在main.c中包含#include ,然后调用__android_log_print()打印输出。

    #include "com_example_l1_ffmpegdemo_MainActivity.h"
    #include 
    #define TAG "JNI_TAG"
    //为了方便调用,将输出宏定义
    #define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

    JNIEXPORT jstring JNICALL Java_com_example_l1_ffmpegdemo_MainActivity_getStringFromNative(JNIEnv *env, jobject obj)
    {
      //输出Logcat
      LOGD("Logcat text");
      //或像C语言printf()一样
      LOGD("%s You are No.%d","Logcat so easy!", 1);
      return (*env)->NewStringUTF(env,"Hello JNI");
    }

然后,在build.gradle中增加链接库。

android {
    ...
    defaultConfig {
        ...
        ndk {
            moduleName "MyLib"  //指定生成动态库的名称
            ldLibs "log"        //增加链接库
        }
    }
    ...
}

重新编译就可以在Logcat窗口看到输出啦~
这里写图片描述

参考:
Using the NDK with Android* Studio
How to get “printf” messages written in NDK application?

你可能感兴趣的:(Android,NDK,android,ndk,jni)