在写J2ME程序的时候,我们一般都希望在真机运行的时候能有一些调试信息,一般在模拟器上运行的话,可以通过System.out.println来输出一些信息,但是在真机上运行的话,就看不到了,因为手机没有控制台啊.那时候如果想确认一些代码的执行情况,经常会用Alert弹出对话框的形式来实现,但是它也有一个不好的地方,那就是当有多个Alert的时候,后面的Alert会把前面的Alert给覆盖掉.后来想,能不能以日志的形式保存起来呢,然后再查看日志呢.参考了LWUIT的框架的LOG,好像它现在的源码还下载不到,只是查看了它的API,觉得用一个管理类通过静态方法统一来管理LOG是很好的一种方法,并且还支持自定义的LOG记录器以及自定义的log显示器.
代码如下:
首先是Logger,它是一个接口,它提供了日志的记录器所要做的一些事情.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hadeslee.insurance.mobile.log;
/**
 * 一个日志生成器要实现的接口
 * @author hadeslee
 */
public interface Logger {
    public static final int FINE = 0;
    public static final int INFO = 10;
    public static final int DEBUG = 20;
    public static final int WARNING = 30;
    public static final int ERROR = 40;
    /**
     * 实现的log方法
     * @param level 级别
     * @param info 内容
     */
    public void log(int level, String info);
    /**
     * 得到所有的日志内容
     * @return 内容
     */
    public String getLogContent();
    /**
     * 清除当前的日志
     */
    public void clearLog();
}
然后是日志显示器,因为日志记录了之后,肯定是要被我们显示出来的,想要如何显示,可以实现此接口.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hadeslee.insurance.mobile.log;
/**
 * 一个用于显示日志的接口,此接口用于LogManager来调用
 * @author hadeslee
 */
public interface LogShower {
    /**
     * 显示日志,由LogManager调用此方法来显示日志
     * 显示日志可以有多种方法,比如可以用列表来显示
     * 也可以用TextArea来显示,还可以用Canvas来显示
     * @param logContent 日志内容
     * @param action 返回的时候要做的动作
     */
    public void showLog(String logContent, BackAction action);
    /**
     * 内部的一个静态接口,实现此接口以供LogShower在
     * 点击了返回之后,要做的事情
     */
    public static interface BackAction {
        /**
         * 点击返回之后要做的事情
         */
        public void back();
    }
}
最后一个类就是LogManager,它只提供了静态方法供调用,它内部有一个默认的Logger实现和一个默认的LogShower实现,在此类中的Shower实现可能不通过,因为我用到了LWUIT里面的一些组件,这个可以自行修改,添加自己的默认实现.
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hadeslee.insurance.mobile.log;
import com.hadeslee.insurance.mobile.log.LogShower.BackAction;
import com.hadeslee.insurance.mobile.util.Util;
import com.sun.lwuit.Command;
import com.sun.lwuit.Form;
import com.sun.lwuit.TextArea;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.layouts.BorderLayout;
/**
 * 日志管理器,所有的日志通过此日志管理器
 * 进行统一的调用
 * 此类相关的两个接口都有相应的默认实现,当然
 * 也可以替换实现
 * @author hadeslee
 */
public final class LogManager {
    private static Logger log = new LoggerImpl();//具体的日志实现类
    private static LogShower shower = new LogShowerImpl();//日志显示者
    private LogManager() {
    }
    /**
     * 安装自己实现的日志记录器
     * @param log 新的日志记录器
     */
    public static void install(Logger log) {
        LogManager.log = log;
    }
    /**
     * 安装自己实现的日志显示器
     * @param shower 新的日志显示器
     */
    public static void install(LogShower shower) {
        LogManager.shower = shower;
    }
    /**
     * 记录INFO级别的日志
     * @param info 日志内容
     */
    public static void info(String info) {
        log.log(Logger.INFO, info);
    }
    /**
     * 记录DEBUG级别的日志
     * @param info 日志内容
     */
    public static void debug(String info) {
        log.log(Logger.DEBUG, info);
    }
    /**
     * 记录ERROR级别的日志
     * @param info 日志内容
     */
    public static void error(String info) {
        log.log(Logger.ERROR, info);
    }
    /**
     * 记录WARNING级别的日志
     * @param info 日志内容
     */
    public static void warning(String info) {
        log.log(Logger.WARNING, info);
    }
    /**
     * 记录FINE级别的日志
     * @param info 日志的内容
     */
    public static void fine(String info) {
        log.log(Logger.FINE, info);
    }
    /**
     * 显示当前日志管理器的日志
     * @param back 要返回的时候,做的动作
     */
    public static void showLog(BackAction back) {
        shower.showLog(log.getLogContent(), back);
    }
    /**
     * 清除当前日志管理器的日志
     */
    public static void clearLog() {
        log.clearLog();
    }
    static class LogShowerImpl implements LogShower {
        public void showLog(String logContent, final BackAction action) {
            Form form = new Form("日志内容");
            form.setScrollable(false);
            final TextArea ta = new TextArea(logContent, 5, 10);
            ta.setEditable(false);
            form.addCommand(new Command("返回") {
                public void actionPerformed(ActionEvent ae) {
                    action.back();
                }
            });
            form.addCommand(new Command("清除") {
                public void actionPerformed(ActionEvent ae) {
                    LogManager.clearLog();
                    ta.setText("");
                }
            });
            form.setLayout(new BorderLayout());
            form.addComponent(BorderLayout.CENTER, ta);
            form.show();
        }
    }
    static class LoggerImpl implements Logger {
        private StringBuffer sb;
        public LoggerImpl() {
            sb = new StringBuffer(1024);
        }
        public void log(int level, String info) {
            sb.append(getPrefix()).append("\n").
                    append(getLevelName(level)).append(":").
                    append(info).append("\n");
        }
        private String getPrefix() {
            return "[" + Thread.currentThread() + "-" + Util.getCurrentTime() + "]";
        }
        private String getLevelName(int level) {
            switch (level) {
                case FINE:
                    return "FINE";
                case INFO:
                    return "INFO";
                case DEBUG:
                    return "DEBUG";
                case WARNING:
                    return "WARNING";
                case ERROR:
                    return "ERROR";
                default:
                    return "UNKNOWN";
            }
        }
        public String getLogContent() {
            return sb.toString();
        }
        public void clearLog() {
            sb.delete(0, sb.length());
        }
    }
}
以上的默认实现中,日志是记录在内存中的,可以用clearLog方法把它清除,当然,也可以自定久记录在RMS里面的日志,并且也要实现相关的clearLog的方法,添加这个方法是因为日志内容不可能让它永远无休止的增长.然后LogManager的showLog方法,就是利用LogShower的实现,把日志显示出来,还有一点,显示日志以后,为了能让LogShower知道,如何返回上一个界面,这里还应该实现一个BackAction方法.
经过自己这几天的使用,发现挺好用的,所以特此和大家分享一下,以提高在开发JAVAME的程序中的一些效率.
在WTK模拟器中的截图如下 :
 
尽管千里冰封
依然拥有晴空
你我共同品味JAVA的浓香.
	posted on 2008-08-04 15:24 
千里冰封 阅读(3321) 
评论(7)  编辑  收藏  所属分类: 
JAVAME