Android 实现自己的LOG信息

在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录。在Android系统中,提供了简单、便利的LOG机制,开发人员可以方便地使用。在这一篇文章中,我们简单介绍在Android内核空间和用户空间中LOG的使用和查看方法。

一. 内核开发时LOG的使用。Android内核是基于Linux Kerne 2.36的,因此,Linux Kernel的LOG机制同样适合于Android内核,它就是有名的printk,与C语言的printf齐名。与printf类似,printk提供格式化输入功能,同时,它也具有所有LOG机制的特点--提供日志级别过虑功能。printk提供了8种日志级别(<linux/kernel.h>):

#define KERN_EMERG "<0>"  /* system is unusable   */
#define KERN_ALERT "<1>"  /* action must be taken immediately */
#define KERN_CRIT "<2>"  /* critical conditions   */
#deinfe KERN_ERR "<3>"  /* error conditions   */
#deinfe KERN_WARNING "<4>"  /* warning conditions   */
#deinfe KERN_NOTICE "<5>"  /* normal but significant condition */
#deinfe KERN_INFO "<6>"  /* informational   */
#deinfe KERN_DEBUG "<7>"  /* debug-level messages   */ 

printk的使用方法:

printk(KERN_ALERT"This is the log printed by printk in linux kernel space.");

KERN_ALERT表示日志级别,后面紧跟着要格式化字符串。

在Android系统中,printk输出的日志信息保存在/proc/kmsg中,要查看/proc/kmsg的内容,参照Android内核源码 在Ubuntu上下载,编译,安装一文,在后台中运行模拟器:

USER-NAME@MACHINE-NAME:~/Android$ emulator &

启动adb shell工具:

USER-NAME@MACHINE-NAME:~/Android$ adb shell

查看/proc/kmsg文件:

root@android:/ # cat  /proc/kmsg

二. 用户空间程序开发时LOG的使用。Android系统在用户空间中提供了轻量级的logger日志系统,它是在内核中实现的一种设备驱动,与用户空间的logcat工具配合使用能够方便地跟踪调试程序。在Android系统中,分别为C/C++ 和Java语言提供两种不同的logger访问接口。C/C++日志接口一般是在编写硬件抽象层模块或者编写JNI方法时使用,而Java接口一般是在应用层编写APP时使用。

Android系统中的C/C++日志接口是通过宏来使用的。在system/core/include/android/log.h定义了日志的级别:

/*
 * Android log priority values, in ascending priority order.
 */
typedef enum android_LogPriority {
 ANDROID_LOG_UNKNOWN = 0,
 ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
 ANDROID_LOG_VERBOSE,
 ANDROID_LOG_DEBUG,
 ANDROID_LOG_INFO,
 ANDROID_LOG_WARN,
 ANDROID_LOG_ERROR,
 ANDROID_LOG_FATAL,
 ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority; 

在system/core/include/cutils/log.h中,定义了对应的宏,如对应于ANDROID_LOG_VERBOSE的宏LOGV:

/*
 * This is the local tag used for the following simplified
 * logging macros. You can change this preprocessor definition
 * before using the other macros to change the tag.
 */
#ifndef LOG_TAG
#define LOG_TAG NULL
#endif 

/*
 * Simplified macro to send a verbose log message using the current LOG_TAG.
 */
#ifndef LOGV
#if LOG_NDEBUG
#define LOGV(...) ((void)0)
#else
#define LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#endif
#endif 

/*
 * Basic log message macro.
 *
 * Example:
 * LOG(LOG_WARN, NULL, "Failed with error %d", errno);
 *
 * The second argument may be NULL or "" to indicate the "global" tag.
 */
#ifndef LOG
#define LOG(priority, tag, ...) \
  LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif 

/*
 * Log macro that allows you to specify a number for priority.
 */
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
  android_printLog(priority, tag, __VA_ARGS__)
#endif 

/*
 * ================================================================
 *
 * The stuff in the rest of this file should not be used directly.
 */
#define android_printLog(prio, tag, fmt...) \
  __android_log_print(prio, tag, fmt) 

因此,如果要使用C/C++日志接口,只要定义自己的LOG_TAG宏和包含头文件system/core/include/cutils/log.h就可以了:

    #define LOG_TAG "MY LOG TAG"

         #include <cutils/log.h>

就可以了,例如使用LOGV:

LOGV("This is the log printed by LOGV in android user space.");

再来看Android系统中的Java日志接口。Android系统在Frameworks层中定义了Log接口:

        (frameworks/base/core/java/android/util/Log.java):

................................................ 

public final class Log { 

................................................ 

 /**
  * Priority constant for the println method; use Log.v.
   */
 public static final int VERBOSE = 2; 

 /**
  * Priority constant for the println method; use Log.d.
   */
 public static final int DEBUG = 3; 

 /**
  * Priority constant for the println method; use Log.i.
   */
 public static final int INFO = 4; 

 /**
  * Priority constant for the println method; use Log.w.
   */
 public static final int WARN = 5; 

 /**
  * Priority constant for the println method; use Log.e.
   */
 public static final int ERROR = 6; 

 /**
  * Priority constant for the println method.
   */
 public static final int ASSERT = 7; 

..................................................... 

 public static int v(String tag, String msg) {
  return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
 } 

 public static int v(String tag, String msg, Throwable tr) {
  return println_native(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr));
 } 

 public static int d(String tag, String msg) {
  return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
 } 

 public static int d(String tag, String msg, Throwable tr) {
  return println_native(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr));
 } 

 public static int i(String tag, String msg) {
  return println_native(LOG_ID_MAIN, INFO, tag, msg);
 } 

 public static int i(String tag, String msg, Throwable tr) {
  return println_native(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr));
 } 

 public static int w(String tag, String msg) {
  return println_native(LOG_ID_MAIN, WARN, tag, msg);
 } 

 public static int w(String tag, String msg, Throwable tr) {
  return println_native(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr));
 } 

 public static int w(String tag, Throwable tr) {
  return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));
 } 

 public static int e(String tag, String msg) {
  return println_native(LOG_ID_MAIN, ERROR, tag, msg);
 } 

 public static int e(String tag, String msg, Throwable tr) {
  return println_native(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr));
 } 

.................................................................. 

因此,如果要使用Java日志接口,只要在类中定义的LOG_TAG常量和引用android.util.Log就可以了:

private static final String LOG_TAG = "MY_LOG_TAG";

        Log.i(LOG_TAG, "This is the log printed by Log.i in android user space.");

要查看这些LOG的输出,可以配合logcat工具。如果是在Eclipse环境下运行模拟器,并且安装了Android插件,那么,很简单,直接在Eclipse就可以查看了:

如果是在自己编译的Android源代码工程中使用,则在后台中运行模拟器:

USER-NAME@MACHINE-NAME:~/Android$ emulator &

启动adb shell工具:

USER-NAME@MACHINE-NAME:~/Android$ adb shell

使用logcat命令查看日志:

root@android:/ # logcat

这样就可以看到输出的日志了。

以上就是Android 自己的LOG信息实现方法,有需要的朋友看下。

(0)

相关推荐

  • Android系统开发中log的使用方法及简单的原理

    在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录.在Android系统中,提供了简单.便利的LOG机制,开发人员可以方便地使用.在平时开发过程中经常需要与log打交道,所以很有必要了解log的使用方法及简单的原理. 1.linux内核的log输出 在标准的linux内核开发过程中,使用printk,这是一个与printf输出打印齐名的函数,同样提供格式化输出功能,只是其有 打印级别且将信息保存到/proc/kmsg日志中,使用c

  • android真机调试时无法显示logcat信息的解决方法介绍

    android真机调试时无法显示logcat信息的解决方法介绍: window-->show view-->android->devices, 打开devices,点击右边的截屏图片的按钮.等到出现截图的时候,logcat就出来信息了!

  • Android开发笔记之:一分钟学会使用Logcat调试程序的详解

    这是个很简单的问题,但每次隔一段时间后使用起来总是会出点乱子.这里记录下Logcat的步骤:1,在Activity里申明tag变量(名字其实是随便的,如下:private static final String tag="yan";2,需要使用logcat输出信息时:Log.i(tag, "屏幕宽度:"+display.getWidth()+" 屏幕高度:"+display.getHeight());3, 双击Logcat,点击"+&q

  • android中ProgressDialog与ProgressBar的使用详解

    一 .ProgressDialogProgressDialog与ProgressBar在UI中动态显示一个加载图标显示程序运行状态.ProgressDialog是继承自Android.app.ProgressDialog所设计的互动对话窗口,使用时,必须新建ProgressDialog对象,在运行时会弹出"对话框"作为提醒,此时应用程序后台失去焦点(即此时无法对UI组件进行操作),直到进程结束后,才会将控制权交给应用程序,如果在Activity当中不希望后台失焦,又希望提示User有某

  • Android中自定义对话框(Dialog)的实例代码

    1.修改系统默认的Dialog样式(风格.主题) 2.自定义Dialog布局文件 3.可以自己封装一个类,继承自Dialog或者直接使用Dialog类来实现,为了方便以后重复使用,建议自己封装一个Dialog类 第一步: 我们知道Android定义个控件或View的样式都是通过定义其style来实现的,查看Android框架中的主题文件,在源码中的路径:/frameworks/base/core/res/res/values/themes.xml,我们可以看到,Android为Dialog定义了

  • android dialog自定义实例详解

    本人工作有一个月多了.对于android很多东西,都有了新的了解或者说真正的掌握.为了让更多的像我这样的小白少走弯路,所以我会坚持将我在工作中遇到的一些比较令我印象深刻的知识点整合出来给大家(顺序是按照我工作到现在的时间来制作的,其实也是想给自己一个记录吧.记录自己一路走来以及以后的路, 至少我想找到曾经的记录都有了). 第一个需求:简单的自定义dialog 需求:创建一个dialog,该dialog具备以下功能: 1.有一个窗口可以显示文章 2.根据需求显示 1)点击同意(不同意),触发对应的

  • Android Studio使用小技巧:自定义Logcat

    我们都知道Logcat是我们Android开发调试最常用的一个工具,但是Android Studio默认的Logcat调试的颜色是一样的,我们不好区分verbose.debug.error等分类信息,今天就来教大家自定义Logcat的提示信息. 打开Preference->Editor->Colors & Fonts->Android Logcat(或者搜索logcat),如果我们默认选择的是Darcula主题会看到如下界面: 这个默认的是无法更改,我们可以点击"Sav

  • logcat命令使用方法和查看android系统日志缓冲区内容的方法

    *注:可以用 adb logcat > 路径/文件名 来保存,此命令执行之时起的全部日志信息到一个文件里,ctrl + C 结束日志输出:后面不加 > 路径/文件名 的话,则在 stdout (终端窗口)中输出!例如:$ adb logcat -v long Checkin *:S > ~/桌面/log.txt 一.在 Java 与 C 语言中输出日志:1) Java 代码在程序中输出日志, 使用 android.util.Log 类的以下 5 个方法:   Log.v().Log.d(

  • android控件封装 自己封装的dialog控件

    自定义dialog肯定是用的很多了但是感觉每次做都是很乱 单纯完成任务而已,现在封装了一下 以后用到直接copy 先上图: 主activity 复制代码 代码如下: package com.su.testcustomdialog; import com.su.testcustomdialog.MyDialog.Dialogcallback; import android.app.Activity; import android.os.Bundle; import android.view.Vie

  • Android开发笔记之:Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)

    在Android群里,经常会有人问我,Android Log是怎么用的,今天我就把从网上以及SDK里东拼西凑过来,让大家先一睹为快,希望对大家入门Android Log有一定的帮助.android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() .根据首字母对应VERBOSE,DEBUG,INFO, WARN,ERROR.1.Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思,平时使用

随机推荐