android studio开发NDK还是很方便的。无论是ndk-build还是cmake方式。c/c++来实现,让开发人员越来越懒。


一:  创建项目

      Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第1张图片



        在include C++ Support 打勾。就是支持C++代码。可以进行C编写。一直next到:

Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第2张图片



    已经完成,直接Finish.其余选项默认即可。


        项目建立完成:

       Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第3张图片

         默认给出一个“Hello from C++”的JNI例子。

        运行即可。那么这就是第一个Android Studio的 JNI项目。就是这么简单。

二:分析

        首先,JNI的项目比较通常的安卓项目,多了一个cpp的文件夹。还有External Build Files 中的Cmake文件。其中gradle中的代码也会有所不同。下面一一看来。

        先看MainActivity里面的:

     

static {    System.loadLibrary("native-lib");}
        表示加载一个native的库。这个库里面就是c/c++编译的。

public native String stringFromJNI();
        声明一个native的接口方法。在这个项目中这个方法在 native-lib的库里面实现了。所以直接调用就可以。

        那在在看native-lib.cpp中:

      

#include #include extern "C"jstringJava_com_xiaoyunchengzhu_jnidemo_MainActivity_stringFromJNI(        JNIEnv *env,        jobject /* this */) {    std::string hello = "Hello from C++";    return env->NewStringUTF(hello.c_str());}
        这个里面的方法就是对stringFromJni接口的实现。返回“Hello from C++”字符串。

       

      在看gradle中:

   

apply plugin: 'com.android.application'android {    compileSdkVersion 23    buildToolsVersion "24.0.0"    defaultConfig {        applicationId "com.xiaoyunchengzhu.jnidemo"        minSdkVersion 15        targetSdkVersion 23        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        externalNativeBuild {            cmake {                cppFlags ""            }        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }    externalNativeBuild {        cmake {            path "CMakeLists.txt"        }    }    productFlavors {    }}dependencies {    compile fileTree(include: ['*.jar'], dir: 'libs')    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:23.0.0'    testCompile 'junit:junit:4.12'}

       

        最新版本native由cmake编译创建,在以前是由ndk-build来创建。cmake文件通常是 CMakeLists.txt。cmake是什么东西呢?cmake是一个编译工具。ok,说到这里,具体怎么用,以后再说。gradle中指定了cmake的flag,,指定了cmake的文件路径。                CMakeLists.txt具体代码:        
# Sets the minimum version of CMake required to build the native# library. You should either keep the default value or only pass a# value of 3.4.0 or lower.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds it for you.# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.             native-lib             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s).             # Associated headers in the same location as their source             # file are automatically included.             src/main/cpp/native-lib.cpp )# Searches for a specified prebuilt library and stores the path as a# variable. Because system libraries are included in the search path by# default, you only need to specify the name of the public NDK library# you want to add. CMake verifies that the library exists before# completing its build.find_library( # Sets the name of the path variable.              log-lib              # Specifies the name of the NDK library that              # you want CMake to locate.              log )# Specifies libraries CMake should link to your target library. You# can link multiple libraries, such as libraries you define in the# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.                       native-lib                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )

         cmake_minimum_required(VERSION 3.4.1):指定创建native库的cmake的最低版本。

        add_library:创建和命名一个库。可以设计库的名字,设置库作为共享库,提供一个相对路劲。

        find_library:自动搜索预构建的库,系统库。

        target_link_libraries:目标库连接。指定的目标库,连接目标库在ndk中。

        其实也不用说,里面的英文解释的很清楚了。我翻译的不太好,这也算是自己的见解。

三:从项目中添加JNI支持

       之前都是一开始就创建的JNI的项目。那么怎么从已经有的项目中添加JNI 的支持呢?

       其实很简单,相比较于在一中,没有什么就主动创建什么,

       1、先创建cpp文件夹,和native库文件也就是cpp文件。

       Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第4张图片


        cpp文件就是jni那一套代码,还有c/c++的代码。

        2、创建cmake的脚本。

       cmake文件的命名必须是CMakeLists.txt。

  这种编译工具类的文件最好和gradle一个文件夹下。

     Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第5张图片


       

          cmake的代码步骤:

        1)版本最低声明:cmake_minimum_required(VERSION 3.4.1)        2)增加native库支持  add_library( native-lib  SHARED  src/main/cpp/native-lib.cpp )
               3)自动搜索预构建库,系统库支持。

                    find_library(log-lib  log )

       4)增加目标库连接:                  arget_link_libraries( native-lib  ${log-lib} )       另外:怎么增加其它的预构建的库呢?比如import-lib是一个外部库。       用add_library(import-lib SHARED IMPORTED) 来添加,2中的路径边成了IMPORTED 标记。来指明是引入的库。并用set_target_properties(import-lib
   
PROPERTIES IMPORTED_LOCATION  import-lib/src/${ANDROID_ABI}/libimport-lib.so)其中 $(ANDROID_ABI)是不同的ABI路径文件夹。这里是so的文件。       如果需要引入头文件 则include_directories( import-lib/include/ )在include目录下的头文件。就被加到里面了。     3、gradle中连接native库和cmake。
gradle中加cmake的路径。
android {
·······
defaultConfig {
······
externalNativeBuild{    cmake{        cppFlags""    }}·····}
·····
     externalNativeBuild {        cmake {        path "CMakeLists.txt"       }   }·······}     cmake还有其它的配置上面是最基本的,简单的配置。还有一些标记的设置,比如cppFlags标记c++标记。如果要打包特殊的ABI配置的so文件则可以增加:
   
android {
·······
ndk {    abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',  'arm64-v8a'}···}

4、c++连接到gradle
Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第6张图片


                      在第3个步骤以前就已经配置完毕了,那么最后一步就是为了在android studio的视图中能看到cpp,和cmake文件。

          效果为:

                    Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第7张图片

             5、在Java代码中加载native库,声明native接口方法。

              

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        TextView textView= (TextView) findViewById(R.id.show);        textView.setText(getValue());    }    public native String getValue();    static {        System.loadLibrary("native-lib");    }}


          我们写了一个简单的native接口getVelue();

         那么在cpp中实现代码为:

          

#include extern "C"jstringJava_com_xiaoyunchengzhu_testdemo_MainActivity_getValue(JNIEnv *env, jobject instance) {    // TODO    return env->NewStringUTF( "hello 我爱和平");}
       

          ok,可以运行试试,屏幕显示的是hello 我爱和平。


        另外:

          其中在Java代码中写native接口的时候有一个智能提示:

   Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第8张图片


          

#include JNIEXPORT jstring JNICALLJava_com_xiaoyunchengzhu_testdemo_MainActivity_getValue(JNIEnv *env, jobject instance) {    // TODO    return (*env)->NewStringUTF(env, "hello world,你好啊");}

             如果继续的话,会创建一个jni文件夹下native-lib.c的文件同时里面已经自动补全好了代码,就剩一个const char*的参数。这个是自动生成的c文件实现方式。这里我就改变了hello world,你好啊。那么只需要cmake的配置就需要变化一下。

 add_library( native-lib  SHARED  src/main/jni/native-lib.c )。ok运行一下。成功。看来依然可以运行用c来实现的native。      c++和c来实现有一个区别就是c++的文件需要加一个extern "C";
         

        那么我们怎么查看生成编译好的.so文件来用呢?这里我们用cmake生成的那么我们去cmake的文件夹下去找:

app\build\intermediates\cmake\  这个文件加下有两个一个是debug,一个是realase。这下面就是生成相应的so库文件。我这里是调试,所以在debug里面下找。

       Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第9张图片

         

   没有指定ABI,所以全部的都生成。

Android NDK探究奥秘一:Android Studio创建第一个JNI项目_第10张图片


        ok,.就到这里了。

       第一个JNI项目就这么完成了。





更多相关文章

  1. Android 导入项目时报Android.jar包丢失解决方法
  2. Android工程中R.java文件的重新生成——(注意资源文件的错误)
  3. Mac上非常好用的免费的Android文件传输工具
  4. GitHub上优秀Android 开源项目
  5. Android遍历获取Office格式(Word,Excel,PPT,PDF)的文件并打开
  6. Android使用xutils3框架实现应用程序内的检查更新下载服务器存放
  7. Android系列教程之Android项目的目录结构

随机推荐

  1. 极光推送实现锁屏推送以及推送给指定的人
  2. Android(安卓)apk动态加载机制的研究(二)
  3. 一键升级 ME860 CWM recovery
  4. android 辅助工具类—— 图片缓冲池
  5. android paint类介绍
  6. Android学习笔记十四之RelativeLayout相
  7. android面試題2
  8. android图像绘制(六)——获取本地图片或拍
  9. Android(安卓)7.0 Camera架构源码分析1 -
  10. Android(安卓)腾讯面试Glide源码解析 3分