android JNI中的log打印

本文介绍了如何在Android的JNI层进行日志打印,包括在Android.mk中添加链接库,定义LOG宏以及使用示例。通过示例代码展示了如何在C/C++代码中使用LOGD, LOGI, LOGW, LOGE和LOGF进行不同级别的日志输出,便于调试和问题排查。
1.导入 #include <android/log.h>

2.在Android.mk 中加上LOCAL_LDLIBS :=-llog

注意:传统方式需要这步,如果是CMake不需要这步,这部分资料详见
注意Android.mk里有一行include $(CLEAR_VARS)
必须把LOCAL_LDLIBS :=-llog放在它后面才有用,
否则相当于没写。

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE    := hello
LOCAL_SRC_FILES := hello.cpp
LOCAL_LDLIBS :=-llog
 
include $(BUILD_SHARED_LIBRARY)

3. 定义LOG 函数

先定义一个全局变量,再定义一些输出的LOG函数:

#define TAG "myDemo-jni" // 这个是自定义的LOG的标识 
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型 
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型 
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型 
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型 
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型 

上述代码中定义的函数
分别对应于Android 的Java代码中的
Log.d(), Log.i(), Log.w(),Log.e(), Log.f()等方法.


4. 完整实例
#include <jni.h>
#include <string.h>
#include <android/log.h>
 
#define TAG    "myhello-jni-test" // 这个是自定义的LOG的标识
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) // 定义LOGD类型
 
 extern "C" {
     JNIEXPORT jstring JNICALL Java_com_snail_helloworld_MainActivity_myhello(JNIEnv * env, jobject obj);
 };
 
 JNIEXPORT jstring JNICALL Java_com_snail_helloworld_MainActivity_myhello(JNIEnv * env, jobject obj)
 {
	 int i = 0;
	 LOGD("########## i = %d", i);
	 return env->NewStringUTF("Hello From CPP");
 }

运行结果如下:
在这里插入图片描述

<think>好的,用户现在的问题是想要在Android JNI中实现日志打印的方法。我需要根据他们之前提供的引用内容来回答这个问题,同时结合之前的讨论,但看起来用户之前的问题是关于修改系统属性返回不同值的,而这次是JNI日志打印。不过用户提供了三个相关的引用,我需要重点参考这些。 首先,用户引用的内容1给出了一个完整的JNI日志打印示例,包括定义不同的日志级别宏,如LOGD、LOGE、LOGI,以及如何在JNI函数中使用这些宏。引用2补充了如何使用__android_log_print函数,并举例说明格式化输出。引用3则比较了__android_log_write和__android_log_print的区别,指出参数形式的不同。 用户当前的问题是如何在Android JNI打印日志,所以需要分步骤说明,包括配置、代码实现、注意事项等。需要注意的是,用户可能已经了解一些基础,但需要明确的步骤和示例代码。 首先,需要确认用户是否已经配置了必要的库和权限。在JNI打印日志需要包含Android的日志库,并在Android.mk或CMakeLists.txt中链接liblog。用户提供的引用1中的代码已经展示了头文件的引入和宏定义,这可能是一个好的起点。 接下来,应该详细说明如何在代码中实际使用这些日志函数。例如,如何定义宏,如何调用不同的日志级别,以及格式化字符串的使用。需要提醒用户注意日志标签的选择,以及不同日志级别的适用场景。 另外,用户可能需要注意权限问题,比如是否需要特定的权限才能输出日志,但实际上在JNI打印日志通常不需要额外权限,只要应用有调试权限即可。但发布时可能需要关闭日志输出,避免性能和安全问题。 还需要考虑不同版本的Android系统对JNI日志的支持是否有变化,但一般来说,__android_log_print是标准方法,兼容性较好。同时,用户可能需要了解如何通过Logcat过滤日志,查看JNI输出的信息。 最后,用户可能想知道如何优化日志输出,比如在发布版本中禁用日志,或者动态控制日志级别。这可以通过预处理宏或运行时配置来实现。 总结来说,回答需要结构清晰,分步骤说明配置、代码示例、使用方法和注意事项,并参考用户提供的引用内容,确保覆盖所有关键点。同时,可能需要补充一些用户未提到的细节,比如CMake配置、日志查看方法等,以提供全面的指导。</think>在Android JNI中实现日志打印需要结合NDK日志库,以下是具体实现方法和注意事项: --- ### 一、基础配置 1. **添加日志库依赖** 在`CMakeLists.txt`中添加: ```cmake find_library(log-lib log) # 必须链接liblog库 target_link_libraries(native-lib ${log-lib}) ``` 2. **引入头文件** ```cpp #include <android/log.h> ``` --- ### 二、日志打印实现 #### 方法1:直接调用原生函数 ```cpp // 基础打印示例 __android_log_print(ANDROID_LOG_DEBUG, "JNI_TAG", "Value=%d, String=%s", 123, "test"); ``` #### 方法2:封装宏定义(推荐) ```cpp #define LOG_TAG "JNI_DEBUG" // 自定义日志标签 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) // 使用示例 JNIEXPORT void JNICALL Java_com_example_NativeLib_logDemo(JNIEnv* env, jobject obj) { int count = 5; LOGD("Debug日志: 当前计数=%d", count); // 输出调试信息 LOGE("发生错误: 文件未找到"); // 输出错误信息 } ``` --- ### 三、高级用法 1. **格式化输出支持** ```cpp LOGI("坐标信息: x=%.2f, y=%.2f", 12.3456f, 78.9012f); // 保留两位小数 ``` 2. **二进制数据打印** ```cpp char data[] = {0x48, 0x65, 0x6C, 0x6C, 0x6F}; LOGD("Hex数据: %02X %02X %02X %02X %02X", data[0], data[1], data[2], data[3], data[4]); ``` --- ### 四、注意事项 1. **性能优化** - 发布版本建议关闭DEBUG日志: ```cpp #ifndef NDEBUG #define LOGD(...) ((void)0) #endif ``` 2. **日志查看技巧** ```bash adb logcat -s JNI_DEBUG:V # 查看指定TAG的详细日志 ``` 3. **线程安全** 多线程环境下建议使用: ```cpp __android_log_write(ANDROID_LOG_WARN, "THREAD", "线程ID: %ld", gettid()); ``` --- ### 五、对比两种日志函数 | 特性 | __android_log_print | __android_log_write | |--------------------|----------------------------------------|----------------------------------| | 参数形式 | 支持格式化字符串和可变参数 | 仅接受固定字符串 | | 使用场景 | 需要动态拼接日志内容时使用 | 输出固定内容或预格式化字符串时使用| | 示例 | `LOGD("状态码: %d", status)` | `__android_log_write(..., "连接超时")` | --- ### 六、实战建议 1. **统一日志规范** - 建议在头文件`native_log.h`中集中管理日志宏 - 为不同模块定义不同TAG,例如:`JNI_NETWORK`、`JNI_GRAPHICS` 2. **敏感信息过滤** ```cpp #ifdef RELEASE_BUILD #define LOGD(...) ((void)0) // 正式包禁用调试日志 #endif ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值