Android使用cmake+ndk输出原生Log

栏目: C · 发布时间: 5年前

内容简介:我们可以在c/cpp代码中用生成好的项目会在很简单,只需要在

我们可以在c/cpp代码中用 print 函数输出log信息,但是这样在 logcat并 不会显示,好在Android已经给我提供了相应的方法解决这个问题:使用 log.h 头文件

开始

  • 创建一个新的Android Studio的工程项目
  • 勾选 Include C++ support 选项
  • 然后就是一路next直到创建项目成功

项目结构

生成好的项目会在 main 目录下创建好 cpp 目录和相应的cpp文件,以及 CmakeLists 文件

Android使用cmake+ndk输出原生Log

CmakeLists

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# 限定cmake支持最低版本
cmake_minimum_required(VERSION 3.4.1)

# 指定so生成到libs目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})

# 配置so库的信息
add_library( # Sets the name of the library.
             # 生成的so库名称,并不需要和c/cpp文件名相同
             # 这里生产的so库名称将为libnative-lib.so
             native-lib

             # Sets the library as a shared library.
             # STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用
             # SHARED:动态库,会被动态链接,在运行时被加载
             # MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接
             SHARED

             # Provides a relative path to your source file(s).
             # 资源文件的路径,可以是多个资源文件
             src/main/cpp/native-lib.cpp )

# 从系统库中查找依赖库
find_library( # Sets the name of the path variable.
              # 设置依赖库的名字,下面链接库的时候会用到
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              
              # 查找log依赖库
              # {sdk-path}/ndk-bundle/sysroot/usr/include/android/log.h
              log )

# 配置库的依赖关系(链接关系)
target_link_libraries( # Specifies the target library.
                       # 目标库
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       # 依赖库,可以是多个
                       ${log-lib} )

复制代码

native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring

JNICALL
Java_com_simple_nativelogdemo_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++ hhahah";
    
    return env->NewStringUTF(hello.c_str());
}
复制代码

app/build.gradle下的android节点块

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.simple.nativelogdemo"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
复制代码

完善代码

很简单,只需要在 cpp 文件中引入 log.h 头文件并调用相关方法即可

#include <jni.h>
#include <string>
//{sdk-path}/ndk-bundle/sysroot/usr/include/android
#include <android/log.h>
//定义输出的TAG
const char * LOG_TGA = "LOG_TGA";

extern "C" JNIEXPORT jstring

JNICALL
Java_com_simple_nativelogdemo_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++ hhahah";
	//输出debug级别的日志信息
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TGA, "hello native log");
    
    return env->NewStringUTF(hello.c_str());
}
复制代码

输出

Android使用cmake+ndk输出原生Log

log.h头文件分析

常用输出函数

/**
 * 输出一个简单的字符串作为log信息
 */
int __android_log_write(int prio, const char* tag, const char* text);

/**
 * 输出一个格式化的字符串作为log信息
 */
int __android_log_print(int prio, const char* tag, const char* fmt, ...)
    
/**
 * 与`__android_log_print`方式相同,区别只是传递参数不同
 */
int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap)
    
/**
* 用于记录断点失败,类型为`ANDROID_LOG_FATAL`
*/
void __android_log_assert(const char* cond, const char* tag, const char* fmt,
                          ...)
复制代码

参数 prio 代表日志级别

日志级别类型

typedef enum android_LogPriority {
  /** For internal use only.  */
  ANDROID_LOG_UNKNOWN = 0,
  /** The default priority, for internal use only.  */
  ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
  /** Verbose logging. Should typically be disabled for a release apk. */
  ANDROID_LOG_VERBOSE,
  /** Debug logging. Should typically be disabled for a release apk. */
  ANDROID_LOG_DEBUG,
  /** Informational logging. Should typically be disabled for a release apk. */
  ANDROID_LOG_INFO,
  /** Warning logging. For use with recoverable failures. */
  ANDROID_LOG_WARN,
  /** Error logging. For use with unrecoverable failures. */
  ANDROID_LOG_ERROR,
  /** Fatal logging. For use when aborting. */
  ANDROID_LOG_FATAL,
  /** For internal use only.  */
  ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
复制代码

我们只需要关注其中的

  • ANDROID_LOG_VERBOSE
  • ANDROID_LOG_DEBUG
  • ANDROID_LOG_INFO
  • ANDROID_LOG_WARN
  • ANDROID_LOG_ERROR

这5个就好了,因为这是我们常用的。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python Cookbook

Python Cookbook

Alex Martelli、Anna Ravenscroft、David Ascher / 高铁军 / 人民邮电出版社 / 2010-5-1 / 99.00元

本书介绍了Python应用在各个领域中的一些使用技巧和方法,从最基本的字符、文件序列、字典和排序,到进阶的面向对象编程、数据库和数据持久化、 XML处理和Web编程,再到比较高级和抽象的描述符、装饰器、元类、迭代器和生成器,均有涉及。书中还介绍了一些第三方包和库的使用,包括 Twisted、GIL、PyWin32等。本书覆盖了Python应用中的很多常见问题,并提出了通用的解决方案。书中的代码和方......一起来看看 《Python Cookbook》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换