Android开发中如何使用C++获取Version.Code版本号
Android NDK C++ 获取Gradle配置版本号的实现方案
这里提供两种常用的实现方式,可根据业务场景选择:
方案1:编译期通过CMake传入版本号(推荐)
该方案不需要运行时调用系统API,性能最高,且无需适配不同Android系统版本,适合获取自身应用版本号的场景。
- 步骤1:修改模块级
build.gradle配置,将版本号作为编译宏传入CMake
android { defaultConfig { // 你项目中原本配置的版本信息 versionCode 101 versionName "1.0.1" externalNativeBuild { cmake { // 定义C++可直接引用的宏,注意版本名是字符串,需要加转义引号 cppFlags "-DAPP_VERSION_CODE=${versionCode}" + " -DAPP_VERSION_NAME=\"${versionName}\"" } } } }
- 步骤2:C++代码中直接使用已定义的宏即可
#include <android/log.h> #define LOG_TAG "VERSION_TEST" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) void logAppVersion() { int versionCode = APP_VERSION_CODE; const char* versionName = APP_VERSION_NAME; LOGD("应用版本号:%d,应用版本名:%s", versionCode, versionName); }
方案2:运行期调用系统API获取
该方案适合需要动态获取自身或其他应用版本号的场景,性能低于编译期传入方案,需要做系统版本适配。
- 实现代码示例:
#include <jni.h> #include <android/log.h> #include <android/api-level.h> #define LOG_TAG "VERSION_TEST" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) long getAppVersionCode(JNIEnv *env, jobject context) { // 获取PackageManager实例 jclass contextCls = env->GetObjectClass(context); jmethodID getPmMethod = env->GetMethodID(contextCls, "getPackageManager", "()Landroid/content/pm/PackageManager;"); jobject pm = env->CallObjectMethod(context, getPmMethod); // 获取当前应用包名 jmethodID getPkgNameMethod = env->GetMethodID(contextCls, "getPackageName", "()Ljava/lang/String;"); jstring pkgName = (jstring)env->CallObjectMethod(context, getPkgNameMethod); // 获取PackageInfo实例 jclass pmCls = env->GetObjectClass(pm); jmethodID getPkgInfoMethod = env->GetMethodID(pmCls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); jobject pkgInfo = env->CallObjectMethod(pm, getPkgInfoMethod, pkgName, 0); // 适配不同系统版本读取版本号 long versionCode = 0; jclass pkgInfoCls = env->GetObjectClass(pkgInfo); if (android_get_device_api_level() >= 28) { // API 28及以上使用longVersionCode字段 jfieldID longVersionCodeField = env->GetFieldID(pkgInfoCls, "longVersionCode", "J"); versionCode = env->GetLongField(pkgInfo, longVersionCodeField); } else { // API 28以下使用versionCode字段 jfieldID versionCodeField = env->GetFieldID(pkgInfoCls, "versionCode", "I"); versionCode = env->GetIntField(pkgInfo, versionCodeField); } // 释放JNI局部引用,避免内存泄漏 env->DeleteLocalRef(contextCls); env->DeleteLocalRef(pm); env->DeleteLocalRef(pkgName); env->DeleteLocalRef(pmCls); env->DeleteLocalRef(pkgInfo); env->DeleteLocalRef(pkgInfoCls); return versionCode; }
注意:使用方案2需要保证传入的JNIEnv和Context对象有效,不要在非JNI线程中直接调用该方法。
内容的提问来源于stack exchange,提问作者HASSNAIN NADEEM
相关产品推荐
相关产品推荐

