zoukankan      html  css  js  c++  java
  • 在Android studio中进行NDK开发

    分类: Android平台

    软硬件环境

    • ubuntu kylin 14.04
    • 红米note增强版
    • Android studio 0.8.6
    • ndk r10c

    前言

    本文的目标是在Android studio中进行NDK的开发。示例是在main activity中显示一个字符串,而字符串的内容是来自于一个C函数。归结于一句话:NDK是为了让上层的java应用能够调用底层的c/c++而设计的。马上进入主题。

    创建工程

    创建一个名为jniDemo的blank activity工程,activity名为MyActivity,在MyActivity类的最后声明一个方法,这个方法会在C函数中去实现,如下图所示,

    drawing

    jni部分

    设置ndk路径,打开local.properties,增加

    ndk.dir=/home/djstava/Workshop/Android/android-studio/ndk 

    点击android studio左下角的Terminal

    cd src/main
    
    javah -d jni -classpath ~/Workshop/Android/android-studio/sdk/platforms/android-4.4.2/android.jar:../../build/intermediates/classes/debug/ com.example.djstava.jnidemo.MyActivity 

    参数意义:

    -d 输出目录,jni是gradle默认的路径    
    -classpath jar的路径,经常碰到的找不到activity的类的错误一般是由这个引起的    
    com.example.djstava.jnidemo.MyActivity 包名+activity 

    这条命令执行完毕后,会在src/main下生成jni目录,并产生头文件com_example_djstava_jnidemo_MyActivity.h,其内容为

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include 
    /* Header for class com_example_djstava_jnidemo_MyActivity */
    
    #ifndef _Included_com_example_djstava_jnidemo_MyActivity
    #define _Included_com_example_djstava_jnidemo_MyActivity
    #ifdef __cplusplus
    extern "C" {
    #endif
    #undef com_example_djstava_jnidemo_MyActivity_MODE_PRIVATE
    #define com_example_djstava_jnidemo_MyActivity_MODE_PRIVATE 0L
    #undef com_example_djstava_jnidemo_MyActivity_MODE_WORLD_READABLE
    #define com_example_djstava_jnidemo_MyActivity_MODE_WORLD_READABLE 1L
    #undef com_example_djstava_jnidemo_MyActivity_MODE_WORLD_WRITEABLE
    #define com_example_djstava_jnidemo_MyActivity_MODE_WORLD_WRITEABLE 2L
    #undef com_example_djstava_jnidemo_MyActivity_MODE_APPEND
    #define com_example_djstava_jnidemo_MyActivity_MODE_APPEND 32768L
    #undef com_example_djstava_jnidemo_MyActivity_MODE_MULTI_PROCESS
    #define com_example_djstava_jnidemo_MyActivity_MODE_MULTI_PROCESS 4L
    #undef com_example_djstava_jnidemo_MyActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
    #define com_example_djstava_jnidemo_MyActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_AUTO_CREATE
    #define com_example_djstava_jnidemo_MyActivity_BIND_AUTO_CREATE 1L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_DEBUG_UNBIND
    #define com_example_djstava_jnidemo_MyActivity_BIND_DEBUG_UNBIND 2L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_NOT_FOREGROUND
    #define com_example_djstava_jnidemo_MyActivity_BIND_NOT_FOREGROUND 4L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_ABOVE_CLIENT
    #define com_example_djstava_jnidemo_MyActivity_BIND_ABOVE_CLIENT 8L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_ALLOW_OOM_MANAGEMENT
    #define com_example_djstava_jnidemo_MyActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_WAIVE_PRIORITY
    #define com_example_djstava_jnidemo_MyActivity_BIND_WAIVE_PRIORITY 32L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_IMPORTANT
    #define com_example_djstava_jnidemo_MyActivity_BIND_IMPORTANT 64L
    #undef com_example_djstava_jnidemo_MyActivity_BIND_ADJUST_WITH_ACTIVITY
    #define com_example_djstava_jnidemo_MyActivity_BIND_ADJUST_WITH_ACTIVITY 128L
    #undef com_example_djstava_jnidemo_MyActivity_CONTEXT_INCLUDE_CODE
    #define com_example_djstava_jnidemo_MyActivity_CONTEXT_INCLUDE_CODE 1L
    #undef com_example_djstava_jnidemo_MyActivity_CONTEXT_IGNORE_SECURITY
    #define com_example_djstava_jnidemo_MyActivity_CONTEXT_IGNORE_SECURITY 2L
    #undef com_example_djstava_jnidemo_MyActivity_CONTEXT_RESTRICTED
    #define com_example_djstava_jnidemo_MyActivity_CONTEXT_RESTRICTED 4L
    #undef com_example_djstava_jnidemo_MyActivity_RESULT_CANCELED
    #define com_example_djstava_jnidemo_MyActivity_RESULT_CANCELED 0L
    #undef com_example_djstava_jnidemo_MyActivity_RESULT_OK
    #define com_example_djstava_jnidemo_MyActivity_RESULT_OK -1L
    #undef com_example_djstava_jnidemo_MyActivity_RESULT_FIRST_USER
    #define com_example_djstava_jnidemo_MyActivity_RESULT_FIRST_USER 1L
    #undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DISABLE
    #define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DISABLE 0L
    #undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DIALER
    #define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_DIALER 1L
    #undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SHORTCUT
    #define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SHORTCUT 2L
    #undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_LOCAL
    #define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
    #undef com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_GLOBAL
    #define com_example_djstava_jnidemo_MyActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
    /*
    * Class:     com_example_djstava_jnidemo_MyActivity
    * Method:    getStringFromJNI
    * Signature: ()Ljava/lang/String;
    */
    JNIEXPORT jstring JNICALL Java_com_example_djstava_jnidemo_MyActivity_getStringFromJNI
    (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif 

    根据产生的头文件,在同级目录创建C源文件,内容如下

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include 
    /* Header for class com_example_djstava_jnidemo_MyActivity */
    
    /*
    * Class:     com_example_djstava_jnidemo_MyActivity
    * Method:    getStringFromJNI
    * Signature: ()Ljava/lang/String;
    */
    JNIEXPORT jstring JNICALL Java_com_example_djstava_jnidemo_MyActivity_getStringFromJNI
    (JNIEnv *env, jobject obj)
    {
        return (*env)->NewStringUTF(env,"Hello android from jni!");
    } 

    gradle配置

    打开build.gradle,在defaultConfig设置项内添加

    ndk {
        moduleName "jniLib" //这是模块名称,在加载时会被用到
    } 

    在defaultConfig设置项后面添加

    flavorGroups "abi"
    
    productFlavors {
        x86 {
            ndk {
                abiFilter "x86"
            }
        }
        arm {
            ndk {
                abiFilter "armeabi-v7a"
            }
        }
        mips {
            ndk {
                abiFilter "mips"
            }
        }
    } 

    在MyActivity中加载jni模块,如下图所示,要去掉前缀lib和后缀.so

    drawing

    修改activity_my.xml

    添加textView的id

    android:id="@+id/jni_text" 

    测试

    不出意外的话,你的app的textView上会出现"Hello android from jni!"。生成的库位于app/build/intermediates/ndk/arm/debug/lib/armeabi-v7a/libjniLib.so,Makefile文件位于/home/djstava/AndroidstudioProjects/jniDemo/app/build/intermediates/ndk/arm/debug/Android.mk,apk文件位于/home/djstava/AndroidstudioProjects/jniDemo/app/build/outputs/apk,当然这些文件的生成都是在studio里做的,对用户是透明的。

    drawing

    参考资料

    1、https://developer.android.com/tools/sdk/ndk/index.html
    2、https://www.youtube.com/watch?v=okLKfxfbz40
    3、http://www.shaneenishry.com/blog/2014/08/17/ndk-with-android-studio/
    4、https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio
    5、https://www.youtube.com/watch?v=e54f6dt9OZo&feature=youtube_gdata

  • 相关阅读:
    miniSpartan6, another Spartan 6 Kit
    XuLA/XuLA2
    Papilio Pro Boards
    STM32 Hardware Development
    Configuring spartan 6 using mcu and spi flash
    STM32 IO口双向问题
    [Projet] Module NFC
    Spartan-6 FPGA Configuration
    TRF7970A IC Communication Interface
    电动门/汽车遥控器拷贝机
  • 原文地址:https://www.cnblogs.com/qingchen1984/p/4962084.html
Copyright © 2011-2022 走看看