NDK学习笔记:AndroidStudio NDK 日志输出 & 断点调试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a360940265a/article/details/84935456

NDK学习笔记:AndroidStudio NDK 日志输出 & 断点调试

一、 Why I need log&debug ?

在我们正常的开发过程中,业务调整必须依靠日志的输出;出现非业务逻辑的异常状况,我们就必须靠断点调试来排查问题。so,我们在NDK开发,怎样设置合理的日志和调试功能呢?以下提供给大家,方便大家提高开发效率。

二、日志 log_common.h

#ifndef LOG_COMMON_H
#define LOG_COMMON_H

#include <android/log.h>
#include <string.h>

#define DEBUG    //注释这行define,就可以一键关闭LOG的输出

// Windows 和 Linux 这两个宏是在 CMakeLists.txt 通过 ADD_DEFINITIONS 定义的
#ifdef Windows
#define __FILENAME__ (strrchr(__FILE__, '\\') + 1) // Windows下文件目录层级是'\\'
#elif Linux
#define __FILENAME__ (strrchr(__FILE__, '/') + 1) // Linux下文件目录层级是'/'
#else
#define __FILENAME__ (strrchr(__FILE__, '/') + 1) // 默认使用这种方式
#endif


#ifdef DEBUG
#define TAG "JNI"
#define LOGV(format, ...) __android_log_print(ANDROID_LOG_VERBOSE, TAG,\
        "[%s][%s][%d]: " format, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define LOGD(format, ...) __android_log_print(ANDROID_LOG_DEBUG, TAG,\
        "[%s][%s][%d]: " format, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define LOGI(format, ...) __android_log_print(ANDROID_LOG_INFO, TAG,\
        "[%s][%s][%d]: " format, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define LOGW(format, ...) __android_log_print(ANDROID_LOG_WARN, TAG,\
        "[%s][%s][%d]: " format, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, TAG,\
        "[%s][%s][%d]: " format, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define LOGV(format, ...)  ;
#define LOGD(format, ...)  ;
#define LOGI(format, ...)  ;
#define LOGW(format, ...)  ;
#define LOGE(format, ...)  ;
#endif // DEBUG

#endif //LOG_COMMON_H

JNI 层的 Android Console Log 方法大家应该都有所了解,但是我们一般不会直接使用原生的接口,而是做一层简单的封装。为了扩展至windows平台,我简单的做了动态宏的编译开关,在CMake编译脚本加上如下语句:


IF (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
    ADD_DEFINITIONS(-DWindows)
ELSE (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux")
    ADD_DEFINITIONS(-DLinux)
ENDIF ()

其实不加也行,默认就是用LInux的,就是告诉大家有这么一回事。至于方法的使用也就贴个示例吧,不多说了。。。

#include "log_commmon.h"

LOGD("hello world");
LOGI("%s", "hello world");
LOGW("%s : %d", "year", 20);
int err_code = -1;
LOGW("%s : %d", "error!", err_code);

三、断点调试

日志可以帮我们解决大部分业务逻辑的繁杂问题,但是有时候我们会出现非业务逻辑的程序bug,这些bug只能依靠动态的断点调试方能找到解决方案。那么我们在NDK开发c/c++的过程中要怎样才能断点调试呢?下面就教大家:

下载NDK调试工具LLDB。在AS依次打开Tools -> Android -> SDKManager,然后在选项卡选择SDK Tools,勾选LLDB。

成功下载安装成功之后(最好重启一下),我们就开始正式配置断点调试的开关。 

1、到对应模块的build.gradle,配置android标签节点下的buildTypes

    buildTypes {
        debug {
            jniDebuggable true
            jniDebuggable = true
        }
    }

2、配置AndroidManifest的Application属性:android:debuggable=“true” (release的时候记得取消掉)

<application
        android:name="org.zzrblog.ZzrApplication"
        android:debuggable="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
</application>

3、最后一步,也是最关键的一步。配置Run/Debug configurations

在哪配置这个东东?   看右图     

然后跟着下图的1~2~3走起。

1、增加一个新的配置项,命名ndk-debug

2、到Genreral选项卡 -> Deployment Target Options -> USB Device(建议真机调试)

3、Debugger选项卡 -> Debug type -> Native

4、Apply -> OK

OK!以上配置搞定之后就能在我们编写的c/c++代码进行断点调试了,运行加载程序的时候,记得要选用新配置的ndk-debug作为启动项。(不行就重启一下)

Note:多进程的情况,此时断点调试功能失效,暂时我也没搞懂为啥,请各位同学知悉。

猜你喜欢

转载自blog.csdn.net/a360940265a/article/details/84935456
ndk