搭建 Windows 下的 Android Studio C++ 开发调试环境

搭建 Windows 下的 Android Studio C++ 开发调试环境

公司有一套祖传的安卓代码,里面用到 C++,因为历史原因,每次 C++ 侧的改动都要在 ubuntu 虚拟机上编译打包,然后再复制到共享文件夹,再在 Windows 上复制到工程中运行,不仅麻烦,而且不能断点调试,所以我花了些时间把它改成可以在 Windows 上编译和调试。公司的代码这里就不展示了,本文以一个测试工程来讲解整个过程,目标是搭建一个在 Windows 下仅用 Android Studio 的开发调试 C++ 的环境,既可以编写 C++ 代码又可以断点调试和打包,不用 CMake 及其它第三方软件,也不用 javah 生成 .h 文件。

第1步,安装 NDK:

在 AS 的 SDK Manager 中安装,如图1所示。安装过程有可能中断,只要反复重试最后一定会成功。记住 NDK 的版本号,后面要用到(版本号可随意选择,越高版本的  C++ 规范越严格)。

图1

第2步,新建工程:

新建工程,如图2所示。这里以传统的 View 框架为例,***pose 框架也是一样的。

图2

第3步,编写 C++侧的配置文件和代码:

在工程中新建以下文件和文件夹,如图3所示。

图3

表1是各文件(夹)的说明。

文件(夹) 说明
app/src/main/cpp/Application.mk 整个工程中所有 C/C++ 模块的配置文件,包含所有模块通用的配置信息
app/src/main/cpp/Android.mk 整个工程中所有 C/C++ 模块的编译描述文件,在这个文件中包含所有 C/C++ 模块的路径
app/src/main/cpp/Test Test 模块的文件夹
app/src/main/cpp/Test/Android.mk Test 模块的编译描述文件
app/src/main/cpp/Test/Test.cpp Test 模块的源代码文件

表1

以下是各文件的内容。

app/src/main/cpp/Application.mk

APP_ABI := arm64-v8a
APP_CPPFLAGS += -fexceptions
APP_PLATFORM := android-24
APP_STL := c++_static
APP_OPTIMA := debug

app/src/main/cpp/Android.mk

my_build_path :=$(call my-dir)
include $(my_build_path)/Test/Android.mk

app/src/main/cpp/Test/Android.mk

my_module_path :=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_PATH := /.
LOCAL_MODULE := Test
LOCAL_C_INCLUDES := $(my_module_path)/
LOCAL_CFLAGS := -D__linux__           \
                -DANDROID_SUPPORT      \
                -DUNICODE             \
                -D_UNICODE            \
                -DLINUX              \
                -DCHART_MERGE           \
                -DMACRO_WH              \
             -DNO_***M_SUPPORT     \
                -DSUPPORT_ITS         \
                -DSUPPORT_HTML        \
                -fsigned-char         \
                -fno-exceptions       \
                -DSUPPORT_LUA         \
                -DUSE_AUTHORIZE       \
LOCAL_SRC_FILES := $(wildcard $(my_module_path)/*.cpp)
include $(BUILD_SHARED_LIBRARY)

app/src/main/cpp/Test/Test.cpp

#include <jni.h>
#include <cstring>

// 测试用的本地方法
jstring GetTestString(JNIEnv* env, jobject) {
    const char* str = "hello c++";
    return env->NewStringUTF(str);
}

// 本地方法数组
JNINativeMethod method_table[] = {
    { "getTestString", "()Ljava/lang/String;", (void*)GetTestString }
};

/**
 * jni 加载事件的响应函数。在这个函数中注册本地方法。
 * @param jvm   java 虚拟机
 */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* jvm, void*) {
    // 获取 jni 环境
    jint jniVersion = JNI_VERSION_1_6;
    JNIEnv* env;
    jvm->GetEnv((void**)&env, jniVersion);

    // 获取使用本地方法的类,注意 className 和 java 侧一致
    const char* className = "***/dlmu/test_android6/MainActivity";
    jclass clazz = env->FindClass(className);
    if (clazz == nullptr) {
        return JNI_FALSE;
    }

    // 注册本地方法
    if (env->RegisterNatives(clazz, method_table, sizeof(method_table) / sizeof(JNINativeMethod)) < 0) {
        return JNI_FALSE;
    }

    return jniVersion;
}

第4步,修改 build.gradle

打开使用本地方法的模块的 build.gradle(本实例是 app 下的 build.gradle),在文件中追加注释部分的内容。

plugins {
    alias(libs.plugins.android.application)
}

android {
    namespace '***.dlmu.test_android6'
    ***pileSdk 35

    defaultConfig {
        applicationId "***.dlmu.test_android6"
        minSdk 24
        targetSdk 35
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        debug {
            // 允许调试本地方法
            jniDebuggable true
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    buildFeatures {
        viewBinding true
    }

    ***pileOptions {
        source***patibility JavaVersion.VERSION_11
        target***patibility JavaVersion.VERSION_11
    }

    // 设置 C++ 的编译配置文件路径
    externalNativeBuild {
        ndkBuild {
            path "src/main/cpp/Android.mk"
        }
    }
    
    // 设置 NDK 版本号
    ndkVersion '27.0.12077973'
}

dependencies {
    implementation libs.app***pat
    implementation libs.material
    implementation libs.activity
    implementation libs.constraintlayout
}

第5步,编写 java 侧代码

public class MainActivity extends App***patActivity {
    /**
     * 测试用的本地方法。
     */
    public native String getTestString();

    /**
     * 静态构造方法。在这个方法中加载动态库。
     */
    static {
        System.loadLibrary("Test");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        final ActivityMainBinding binding = ActivityMainBinding.inflate(super.getLayoutInflater());
        super.setContentView(binding.getRoot());
        View***pat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsets***pat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        // 调用测试方法
        binding.tvTest.setText(this.getTestString());
    }
}

第6步,运行

同步一下工程就可以运行了,在手机屏幕上显示 hello c++,也可以在 C++ 文件中下断点。

最后补充一点,如果是在非 app 模块中使用 C++,且在该模块的 build.gradle 中设置了

ndk {
    abiFilters "......"
}

那么 app 模块中也要有相同的设置,否则打包后的 apk 中没有 so 文件,程序当然也会闪退。

全文完。

转载请说明出处内容投诉
CSS教程网 » 搭建 Windows 下的 Android Studio C++ 开发调试环境

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买