AndroidStudio NDK环境3种搭建方式

一、前言

如今Android开发IDE都是使用的AndroidStudio,之前我写过一篇文章介绍的是如何在Eclipse中搭建NDK环境 Android NDK --初始android NDK
这边博客介绍下在AndroidStudio中搭建NDK环境的三种方式。

二、知识点概述

本片我们将从以下几点初步认识、创建Android NDK:
1.Java加载/调用NDK端的代码;
2.本地 c++代码的编写;
3.编写构建系统文件(android.mk、application.mk)
4.通过构建系统编译c++代码
4.1、通过Gradle搭建NDK环境;
4.2、通过NDKBuild搭建NDK环境(重点介绍);
4.3、通过CMake搭建NDK环境;

三、知识点详解

(1)Java加载/调用NDK端的代码

1、Java端代码:

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("helloworld");
    }

    private TextView mDataView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        mDataView = (TextView) this.findViewById(R.id.tv_data);
        mDataView.setText(getStrFromNative());
    }

    private native String getStrFromNative();
}

2、在AndroidStudio打开命令行界面,cd app/src/main/java 运行

javah com.zhangjunling.ndk_environment_gradle.MainActivity

这时会自动在目录下生成一个com_zhangjunling_ndk_environment_gradle_MainActivity.h文件,把文件拷贝到 main/jni 目录中。

(2) 本地 c++代码的编写

由于本编只是介绍NDK环境的搭建问题,所以代码越简单越容易把所有的精力都放在环境搭建上,所以c++代码只是简单的 HelloWrold程序;

helloworld.cpp

#include "com_zhangjunling_ndk_environment_gradle_MainActivity.h"

JNIEXPORT jstring JNICALL Java_com_zhangjunling_ndk_1environment_1gradle_MainActivity_getStrFromNative
  (JNIEnv *env, jobject obj){
      return env->NewStringUTF("Hello. I'm form native");
}

(3)编写构建系统文件

在jni目录下创建Android.mk、Application.mk文件内容如下:
Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := helloworld
LOCAL_SRC_FILES := helloworld.cpp

include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_STL := gnustl_static
APP_ABI := armeabi

关于构建系统里面的键值对的含义,现在先不关心,下篇文章我会详细介绍;

(4)通过构建系统编译c++代码

通过Gradle搭建NDK环境

Gradle是androidstudio上的编译工具,我们可以通过从项目下的local.properties获取ndk.dir=xxxxxxxx,获取ndk-build路径,然后执行ndk-build便可以编译出需要的动态库文件;gradle的语法这里不在进行讲解,感兴趣的可以从网络上获取资料学习;
build.gradle代码如下:

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.zhangjunling.ndk_environment_gradle"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDir 'src/main/libs'
            jni.srcDirs = []
        }
    }
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

String getNdkBuildPath() {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    def ndkBuildingDir = properties.getProperty("ndk.dir")
    def ndkBuildPath = ndkBuildingDir
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd'
    } else {
        ndkBuildPath = ndkBuildingDir + '/ndk-build'
    }
    return ndkBuildPath
}

task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
    println('executing ndkBuild')
    def ndkBuildPath = getNdkBuildPath();
    commandLine ndkBuildPath, '-j8', '-C', file('src/main').absolutePath
}

task ndkClean(type: Exec, description: 'clean JNI libraries') {
    println('executing ndkBuild clean')
    def ndkBuildPath = getNdkBuildPath();
    commandLine ndkBuildPath, 'clean', '-C', file('src/main').absolutePath
}
clean.dependsOn 'ndkClean'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

现在我们可以先通过工具栏 Build/ReBuild Project,观察到libs目录、obj目录自动产生,没有报错。这可以说明我们的配置没有什么问题;可以运行项目看到:

Hello. I'm form native
通过NDKBuild搭建NDK环境(重点介绍)

通过ndk-build交叉编译c++本地代码是我们重点学习的,后面我会重点介绍通过ndk-build交叉编译出我们需要的动态库。本篇只介绍环境的搭建。
Android.mk构建好了之后,ndk-build环境就比较简单了,步骤:

项目右键->Link C++ Project With Gradle 
路径选择Android.mk 就OK 了。
通过CMake搭建NDK环境

CMake搭建NDK环境有两种方式:
1、与ndk-build相同

项目右键->Link C++ Project With Gradle 
路径选择CMakeList.txt 就OK 了。

2、在Create Android Project的时候底部勾选Include C++ support,项目创建好了之后,自动创建好了NDK环境。我们可以在此基础上开发NDK。

项目路径:AndroidStudio环境搭建源码

你可能感兴趣的:(NDK)