[2016-06-30]最新的log4j已经集成在DR_support_lib库中

具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/tree/master

[2016-06-28] 1 增加log4j的支持
[2016-06-28] 2 增加全局异常处理(可自定义程序崩溃提示消息,自定义发送错误报告到服务器)
[2016-06-28] 3 增加两种应用退出方法:① appExit,结束掉所有Acitivity的生命周期,正常退出;② appKill,结束掉所有Acitivity的生命周期,杀掉程序进程后退出。
[2016-06-29] 4 增加透明状态栏和导航栏(默认开启,蓝色背景)

1、新建Android项目

Project: AndroidLog4j

Package:cn.darkranger.log

Activity:MainActivity

2、在libs中添加log4j-1.2.17.jar包

3、添加android-logging-log4j-1.0.3.jar

我看了一下,这里面只有两个类,我就用反编译工具反编译成了java文件,写入代码中了

LogCatAppender.java(主要作用是将log在控制台的输出转化为Android中的LogCat输出)

package cn.darkranger.log.log4j;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent; import android.util.Log; /**
* 源自 android-logging-log4j-1.0.3.jar
*
* @author Administrator
*/
public class LogCatAppender extends AppenderSkeleton {
protected Layout tagLayout; public LogCatAppender(Layout messageLayout, Layout tagLayout) {
this.tagLayout = tagLayout;
setLayout(messageLayout);
} public LogCatAppender(Layout messageLayout) {
//这里定义的是Tag名称
this(messageLayout, new PatternLayout("%c"));
} public LogCatAppender() {
this(new PatternLayout("%c"));
} protected void append(LoggingEvent le) {
switch (le.getLevel().toInt()) {
case 5000:
if (le.getThrowableInformation() != null) {
Log.v(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else {
Log.v(getTagLayout().format(le), getLayout().format(le));
}
break;
case 10000:
if (le.getThrowableInformation() != null) {
Log.d(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else {
Log.d(getTagLayout().format(le), getLayout().format(le));
}
break;
case 20000:
if (le.getThrowableInformation() != null) {
Log.i(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else {
Log.i(getTagLayout().format(le), getLayout().format(le));
}
break;
case 30000:
if (le.getThrowableInformation() != null) {
Log.w(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else {
Log.w(getTagLayout().format(le), getLayout().format(le));
}
break;
case 40000:
if (le.getThrowableInformation() != null) {
Log.e(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else {
Log.e(getTagLayout().format(le), getLayout().format(le));
}
break;
case 50000:
if (le.getThrowableInformation() != null) {
Log.wtf(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
} else
Log.wtf(getTagLayout().format(le), getLayout().format(le));
break;
}
} public void close() {
} public boolean requiresLayout() {
return true;
} public Layout getTagLayout() {
return this.tagLayout;
} public void setTagLayout(Layout tagLayout) {
this.tagLayout = tagLayout;
}
}

LogConfig.java(主要作用是配置一些基本的信息)

package cn.darkranger.log.log4j;

import java.io.IOException;

import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.helpers.LogLog; /**
* 源自 android-logging-log4j-1.0.3.jar
*
* @author Administrator
*/
public class LogConfig {
private Level rootLevel = Level.DEBUG;
/**
* ### log文件的格式
*
* ### 输出格式解释:
* ### [%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n
*
* ### %d{yyyy-MM-dd HH:mm:ss}: 时间,大括号内是时间格式
* ### %c: 全类名
* ### %M: 调用的方法名称
* ### %F:%L 类名:行号(在控制台可以追踪代码)
* ### %n: 换行
* ### %p: 日志级别,这里%-5p是指定的5个字符的日志名称,为的是格式整齐
* ### %m: 日志信息 * ### 输出的信息大概如下:
* ### [时间{时间格式}][信息所在的class.method(className:lineNumber)] 换行
* ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
*/
private String filePattern = "[%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n"; /**
* ### LogCat控制台输出格式
*
* ### [Class: 信息所在的class.method(className:lineNumber)] 换行
* ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
*/
private String logCatPattern = "[Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n";
private String fileName = "android-log4j.log";
private int maxBackupSize = 5;
private long maxFileSize = 1024 * 1024 * 5L;
private boolean immediateFlush = true;
private boolean useLogCatAppender = true;
private boolean useFileAppender = true;
private boolean resetConfiguration = true;
private boolean internalDebugging = false; public LogConfig() {
} public LogConfig(String fileName) {
setFileName(fileName);
} public LogConfig(String fileName, Level rootLevel) {
this(fileName);
setRootLevel(rootLevel);
} public LogConfig(String fileName, Level rootLevel, String filePattern) {
this(fileName);
setRootLevel(rootLevel);
setFilePattern(filePattern);
} public LogConfig(String fileName, int maxBackupSize, long maxFileSize, String filePattern, Level rootLevel) {
this(fileName, rootLevel, filePattern);
setMaxBackupSize(maxBackupSize);
setMaxFileSize(maxFileSize);
} public void configure() {
Logger root = Logger.getRootLogger(); if (isResetConfiguration()) {
LogManager.getLoggerRepository().resetConfiguration();
} LogLog.setInternalDebugging(isInternalDebugging()); if (isUseFileAppender()) {
configureFileAppender();
} if (isUseLogCatAppender()) {
configureLogCatAppender();
} root.setLevel(getRootLevel());
} public void setLevel(String loggerName, Level level) {
Logger.getLogger(loggerName).setLevel(level);
} private void configureFileAppender() {
Logger root = Logger.getRootLogger(); Layout fileLayout = new PatternLayout(getFilePattern());
RollingFileAppender rollingFileAppender;
try {
rollingFileAppender = new RollingFileAppender(fileLayout, getFileName());
} catch (IOException e) {
throw new RuntimeException("Exception configuring log system", e);
} rollingFileAppender.setMaxBackupIndex(getMaxBackupSize());
rollingFileAppender.setMaximumFileSize(getMaxFileSize());
rollingFileAppender.setImmediateFlush(isImmediateFlush()); root.addAppender(rollingFileAppender);
} private void configureLogCatAppender() {
Logger root = Logger.getRootLogger();
Layout logCatLayout = new PatternLayout(getLogCatPattern());
LogCatAppender logCatAppender = new LogCatAppender(logCatLayout); root.addAppender(logCatAppender);
} public Level getRootLevel() {
return this.rootLevel;
} public void setRootLevel(Level level) {
this.rootLevel = level;
} public String getFilePattern() {
return this.filePattern;
} public void setFilePattern(String filePattern) {
this.filePattern = filePattern;
} public String getLogCatPattern() {
return this.logCatPattern;
} public void setLogCatPattern(String logCatPattern) {
this.logCatPattern = logCatPattern;
} public String getFileName() {
return this.fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
} public int getMaxBackupSize() {
return this.maxBackupSize;
} public void setMaxBackupSize(int maxBackupSize) {
this.maxBackupSize = maxBackupSize;
} public long getMaxFileSize() {
return this.maxFileSize;
} public void setMaxFileSize(long maxFileSize) {
this.maxFileSize = maxFileSize;
} public boolean isImmediateFlush() {
return this.immediateFlush;
} public void setImmediateFlush(boolean immediateFlush) {
this.immediateFlush = immediateFlush;
} public boolean isUseFileAppender() {
return this.useFileAppender;
} public void setUseFileAppender(boolean useFileAppender) {
this.useFileAppender = useFileAppender;
} public boolean isUseLogCatAppender() {
return this.useLogCatAppender;
} public void setUseLogCatAppender(boolean useLogCatAppender) {
this.useLogCatAppender = useLogCatAppender;
} public void setResetConfiguration(boolean resetConfiguration) {
this.resetConfiguration = resetConfiguration;
} public boolean isResetConfiguration() {
return this.resetConfiguration;
} public void setInternalDebugging(boolean internalDebugging) {
this.internalDebugging = internalDebugging;
} public boolean isInternalDebugging() {
return this.internalDebugging;
}
}

4、编写LogUtil.java工具类(主要作用是重新配置Log4j的一些参数,设置成为合适自己项目的log,在这里我们通过调用LogUtil.configLog()就可以了,简洁)

LogUtil.java

package cn.darkranger.log.log4j;

import java.io.File;
import java.util.Locale; import org.apache.log4j.Level; import android.os.Environment; /**
* LogUtil 工具类
*
* @author Administrator
*
*/
@SuppressWarnings("all")
public class LogUtil { /** 这里的AppName决定log的文件位置和名称 **/
private static final String APP_NAME = "MyApp"; /** 设置log文件全路径,这里是 MyApp/Log/myapp.log **/
private static final String LOG_FILE_PATH = Environment.getExternalStorageDirectory() + File.separator + APP_NAME
+ File.separator + "Log" + File.separator + APP_NAME.toLowerCase(Locale.CHINA) + ".log"; /**
* ### log文件的格式
*
* ### 输出格式解释:
* ### [%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n
*
* ### %d{yyyy-MM-dd HH:mm:ss}: 时间,大括号内是时间格式
* ### %c: 全类名
* ### %M: 调用的方法名称
* ### %F:%L 类名:行号(在控制台可以追踪代码)
* ### %n: 换行
* ### %p: 日志级别,这里%-5p是指定的5个字符的日志名称,为的是格式整齐
* ### %m: 日志信息 * ### 输出的信息大概如下:
* ### [时间{时间格式}][信息所在的class.method(className:lineNumber)] 换行
* ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
*/
private static final String LOG_FILE_PATTERN = "[%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n"; /** 生产环境下的log等级 **/
private static final Level LOG_LEVEL_PRODUCE = Level.ALL; /** 发布以后的log等级 **/
private static final Level LOG_LEVEL_RELEASE = Level.INFO; /**
* 配置log4j参数
*/
public static void configLog(){ LogConfig logConfig = new LogConfig(); /** 设置Log等级,生产环境下调用setLogToProduce(),发布后调用setLogToRelease() **/
setLogToProduce(logConfig); logConfig.setFileName(LOG_FILE_PATH); logConfig.setLevel("org.apache", Level.ERROR); logConfig.setFilePattern(LOG_FILE_PATTERN); logConfig.setMaxFileSize(1024 * 1024 * 5); logConfig.setImmediateFlush(true); logConfig.configure(); } /**
* 将log设置为生产环境
*
* @param logConfig
*/
private static void setLogToProduce(LogConfig logConfig) {
logConfig.setRootLevel(LOG_LEVEL_PRODUCE);
} /**
* 将log设置为发布以后的环境
*
* @param logConfig
*/
private static void setLogToRelease(LogConfig logConfig) {
logConfig.setRootLevel(LOG_LEVEL_RELEASE);
}
}

5、编写MyApplication.java(继承Application,然后在onCreate()中调用LogUtil.configLog()方法来配置Log4j,这样程序一开始就相当于初始化了Log4j的配置)

package cn.darkranger.log.application;

import org.apache.log4j.Logger;

import android.app.Application;
import cn.darkranger.log.log4j.LogUtil; public class MyApplication extends Application { @Override
public void onCreate() {
super.onCreate(); //配置log4j基本参数
LogUtil.configLog(); //获取Application Log
Logger log = Logger.getLogger(MyApplication.class); //输出MyApplication的信息
log.info("Log4j Is Ready and My Application Was Created Successfully! ");
} }

6、修改AndroidManifest.xml(主要有两个地方,一是添加读取存储的权限,二是指定Application为我们刚刚写的MyApplication)

有下划线的地方就是我们添加的xml代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.darkranger.log"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="22" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application
android:name="cn.darkranger.log.application.MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="cn.darkranger.log.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

 7、使用Log4j

  (1)创建Logger实例

    private static Logger log = Logger.getLogger(YourClassName.class);

  (2)在代码中用log记录信息

    log.info("onCreate()");
    log.fatal("this is fatal!");
    log.error("this is error!");
    log.warn("this is warn!");
    log.info("this is info!");
    log.debug("this is debug!");
    log.trace("this is trace!");

  (3)MainActivity.java中的示例(红色的部分就是log的记录)

package cn.darkranger.log;

import org.apache.log4j.Logger;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem; public class MainActivity extends AppCompatActivity {
private static Logger log = Logger.getLogger(MainActivity.class); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
log.info("onCreate()");
log.fatal("this is fatal!");
log.error("this is error!");
log.warn("this is warn!");
log.info("this is info!");
log.debug("this is debug!");
log.trace("this is trace!");
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
log.info("onCreateOptionsMenu()");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

 8、结果展示:


  控制台输出(自定义logcat输出格式:"[Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n"):

  平板中的Log位置:计算机\Galaxy Tab A\Tablet\MyApp\Log\myapp.log(相对于计算机)

           设备存储\MyApp\Log\myapp.log(相对于平板)

[2016-06-16 17:14:54][Class: cn.darkranger.log.application.MyApplication.onCreate(MyApplication.java:21)]
[Level: INFO ] - Msg: Log4j Is Ready and My Application Was Created Successfully!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:17)]
[Level: INFO ] - Msg: onCreate()
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:18)]
[Level: FATAL] - Msg: this is fatal!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:19)]
[Level: ERROR] - Msg: this is error!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:20)]
[Level: WARN ] - Msg: this is warn!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:21)]
[Level: INFO ] - Msg: this is info!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:22)]
[Level: DEBUG] - Msg: this is debug!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:23)]
[Level: TRACE] - Msg: this is trace!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreateOptionsMenu(MainActivity.java:30)]
[Level: INFO ] - Msg: onCreateOptionsMenu()

项目示例地址:

http://files.cnblogs.com/files/wrcold520/AndroidLog4j.zip

Android应用中添加Log4j的示例的更多相关文章

  1. Android.mk中添加宏定义

    在Boardconfig.mk 中添加一个 IS_FLAG := true 由于Boardconfig.mk和各目录的Android.mk是相互关联的 所以我们可以在Android.mk 中添加 一个 ...

  2. 关于如何正确地在android项目中添加第三方jar包

    在android项目中添加第三方jar包虽然不是一个很复杂的问题,但是确实给很多开发者带来了不小的困扰.我自己就曾经碰到过calss not found exception.error inflati ...

  3. 如何在Android Studio中添加注释模板信息?

    如何在Android Studio中添加注释模板信息? 在开发程序的时候,我们一般都会给文件自动添加上一些关于文件的注释信息,比如开发者的名字,开发的时间,开发者的联系方式等等.那么在android ...

  4. Android.mk中添加宏定义【转】

    本文转载自:http://blog.csdn.net/huangyabin001/article/details/38302021 在Boardconfig.mk 中添加一个 IS_FLAG := t ...

  5. Google官方关于Android架构中MVP模式的示例续-DataBinding

    基于前面的TODO示例,使用Data Binding库来显示数据并绑定UI元素的响应动作. 这个示例并未严格遵循 Model-View-ViewModel 或 Model-View-Presenter ...

  6. android Camera 中添加一种场景模式

    转自:http://blog.csdn.net/fulinwsuafcie/article/details/8833652 首先,来了解一下什么是场景模式. 最简单的方法当然是google了,这里有一 ...

  7. 【转】android Camera 中添加一种场景模式

    http://blog.csdn.net/fulinwsuafcie/article/details/8833652 首先,来了解一下什么是场景模式. 最简单的方法当然是google了,这里有一篇文章 ...

  8. 类中添加log4j日志

    在编写代码的时候需要随时查看工作日志,查看工作日志的好处就是随时能检查出错误.所以我一般就需要在编写代码的前期添加工作日志,以便更好的查看相关错误输出. 以一个springmvc小demo为例子  主 ...

  9. 在android工程中添加图片资源(转加)

    在Android工程中,每添加一个资源,就会在gen目录下的R.java中自动生成一个新的静态整型变量来指向这个资源.程序文件中调用资源的时候,先在R.java中找到变量名,然后根据变量值查找资源. ...

随机推荐

  1. 01 git 概念

    本文转自“廖雪峰的git教程” 集中式版本控制系统:版本库是集中存放在中央服务器的,中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆. 分布式版 ...

  2. [GO]随机数的使用

    package main import ( "math/rand" "time" "fmt" ) func main() { //设置种子, ...

  3. javascript总结2: Date对象

    1 Date 对象 Date 对象用于处理日期与时间. Date()的方法很多,这里只总结工作必备的方法! 2 常用方法 创建个 Date 对象:const mydate=new Date(); &l ...

  4. 将“100px” 转换为100

    parseInt("100px") //结果是100

  5. Android getDimension,getDimensionPixelOffset,getDimensionPixelSize

    1.例如在onMeasure(int , int)方法中可能要获取自定义属性的值.如: TypedArray a = context.obtainStyledAttributes(attrs, R.s ...

  6. C# 给图片添加透明的文字、图片水印

    #region 添加水印 /// <summary> /// 添加文字水印 /// </summary> /// <param name="image" ...

  7. IE11下使用fixed定位时鼠标滚动不平滑

    很久不用IE了,近期做兼容性测试发现一个fixed定位的问题,当元素使用fixed定位时,其应该不随页面滚动,在chrome/firefox/edge下都很完美,元素完全不动,但是使用IE11时,如果 ...

  8. thedao

    TheDao 简化版解释 the Dao 合约 contract f1{ function transfer() { if (acccount[m]>=100) { m.send(100) ac ...

  9. Jmeter的主要元件及元件的执行顺序

    一.JMeter的主要元素 1.Test Pan(测试计划) Jmeter中的测试计划包括一个或者一组的测试用例,一个Thread Group可以认为是一个测试用例,一个测试计划中可以包括多个Thre ...

  10. CString、string、string.h的区别

    CString.string.string.h的区别   CString:CString是MFC或者ATL中的实现,是MFC里面封装的一个关于字符串处理的功能很强大的类,只有支持MFC的工程才能使用. ...