当前位置:  编程技术>移动开发
本页文章导读:
    ▪惯用log4j配置        常用log4j配置 常用log4j配置常用log4j配置,一般可以采用两种方式,.properties和.xml,下面举两个简单的例子:一、log4j.properties### 设置org.zblog域对应的级别INFO,DEBUG,WARN,ERROR和输出地A1,A2 ##log4j.........
    ▪ 一部分项目工程配置文件的说明        部分项目工程配置文件的说明 1、web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:.........
    ▪ 电池及充电相干的服务BatteryService的实现       电池及充电相关的服务BatteryService的实现 BatteryService作为电池及充电相关的服务,它的实现非常简单:o 监听UEvent,读取sysfs里中的状态。实现了一个UEvent的观察者。uevent是Linux内核用来向.........

[1]惯用log4j配置
    来源: 互联网  发布时间: 2014-02-18
常用log4j配置
常用log4j配置
常用log4j配置,一般可以采用两种方式,.properties和.xml,下面举两个简单的例子:
一、log4j.properties
### 设置org.zblog域对应的级别INFO,DEBUG,WARN,ERROR和输出地A1,A2 ##
log4j.category.org.zblog=ERROR,A1
log4j.category.org.zblog=INFO,A2
log4j.appender.A1=org.apache.log4j.ConsoleAppender
### 设置输出地A1,为ConsoleAppender(控制台) ##
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
### 设置A1的输出布局格式PatterLayout,(可以灵活地指定布局模式)##
log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
### 配置日志输出的格式##
log4j.appender.A2=org.apache.log4j.RollingFileAppender
### 设置输出地A2到文件(文件大小到达指定尺寸的时候产生一个新的文件)##
log4j.appender.A2.File=E:/study/log4j/zhuwei.html
### 文件位置##
log4j.appender.A2.MaxFileSize=500KB
### 文件大小##
log4j.appender.A2.MaxBackupIndex=1
log4j.appender.A2.layout=org.apache.log4j.HTMLLayout
##指定采用html方式输出
二、log4j.xml
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="org.zblog.all" >
<!-- 设置通道ID:org.zblog.all和输出方式:org.apache.log4j.RollingFileAppender -->
   <param name="File" value="E:/study/log4j/all.output.log" /><!-- 设置File参数:日志输出文件名 -->
   <param name="Append" value="false" /><!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
   <param name="MaxBackupIndex" value="10" />
   <layout >
       <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 设置输出文件项目和格式 -->
   </layout>
</appender>
<appender name="org.zblog.zcw" >
   <param name="File" value="E:/study/log4j/zhuwei.output.log" />
   <param name="Append" value="true" />
   <param name="MaxFileSize" value="10240" /> <!-- 设置文件大小 -->
   <param name="MaxBackupIndex" value="10" />
   <layout >
       <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
   </layout>
</appender>
<logger name="zcw.log"> <!-- 设置域名限制,即zcw.log域及以下的日志均输出到下面对应的通道中 -->
   <level value="debug" /><!-- 设置级别 -->
   <appender-ref ref="org.zblog.zcw" /><!-- 与前面的通道id相对应 -->
</logger>
<root> <!-- 设置接收所有输出的通道 -->
   <appender-ref ref="org.zblog.all" /><!-- 与前面的通道id相对应 -->
</root>
</log4j:configuration>
三、配置文件加载方法:
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.DOMConfigurator;
public class Log4jApp {
   public static void main(String[] args) {
       DOMConfigurator.configure("E:/study/log4j/log4j.xml");//加载.xml文件
       //PropertyConfigurator.configure("E:/study/log4j/log4j.properties");//加载.properties文件
       Logger log=Logger.getLogger("org.zblog.test");
       log.info("测试");
   }
}
四、项目使用log4j
在web 应用中,可以将配置文件的加载放在一个单独的servlet中,并在web.xml中配置该servlet在应用启动时候加载。对于在多人项目中,可以给每一个人设置一个输出通道,这样在每个人在构建Logger时,用自己的域名称,让调试信息输出到自己的log文件中。
五、常用输出格式
# -X号:X信息输出时左对齐;
# %p:日志信息级别
# %d{}:日志信息产生时间
# %c:日志信息所在地(类名)
# %m:产生的日志具体信息
# %n:输出日志信息换行


---------------------

使用方法介绍:
1、定义配置文件
    首先使用配置文件将使我们的应用程序更加灵活配置log日志输出方式包括输出优先级、输出目的地、输出格式。Log4j支持两种配置文件格式,一种是 XML格式的文件,一种是Java特性文件log4j.properties(键=值)。下面将介绍使用log4j.properties文件作为配置文件的方法:
  ①配置根Logger,其语法为:
  log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者自定义的级别。其中的OFF表示关闭输出日志,ALL表示输出所有的日志信息。
Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来,而包括INFO以及高于INFO级别的日志信息都将被输出。
而后面的appenderName就是指定日志信息输出到哪个地方。可同时指定多个输出目的地。根据用户的不同需求,还可以定义不同的Logger,并且不同的Logger可以使用不同的日志输出级别和不同的日志输出目的地。
  ②配置日志信息输出目的地Appender,其语法为:
  log4j.appender.appenderName = fully.qualified.name.of.appender.class
  log4j.appender.appenderName.option1 = value1
  …
  log4j.appender.appenderName.option = valueN
其中的Log4j.appender.appenderName用于配置Appender的类型,而后面的参数则可以用来配置所使用的Appender的参数值。使用的Appender不同需要配置的参数就不同。
Log4j提供的默认的appender有以下几种:
  org.apache.log4j.ConsoleAppender(控制台),
  org.apache.log4j.FileAppender(文件),
  org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
  org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
  org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
  ③配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
  log4j.appender.appenderName.layout.option1 = value1
  …
  log4j.appender.appenderName.layout.option = valueN
其中log4.appender.appenderName.layout参数用于指定所使用的日志信息的布局类。后面的参数用于配置该布局类初始化时的参数。具体参数的数量依赖于所使用的布局类。
其中,Log4j提供的layout有以下几种:
  org.apache.log4j.HTMLLayout(以HTML表格形式布局),
  org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
  org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
  org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
  %r 输出自应用启动到输出该log信息耗费的毫秒数
  %c 输出所属的类目,通常就是所在类的全名
  %t 输出产生该日志事件的线程名
  %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
  %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
  %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)


例子1:
显示日期和log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %m%n
打印的信息是:
2002-11-12 11:49:42,866 SELECT * FROM Role WHERE 1=1 order by createDate desc

例子2:
显示日期,log发生地方和log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %l "#" %m%n
2002-11-12 11:51:46,313 cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409) "#"
SELECT * FROM Role WHERE 1=1 order by createDate desc
 
例子3:
显示log级别,时间,调用方法,log信息
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n
log信息:
[DEBUG] 2002-11-12 12:00:57,376
method:cn.net.unet.weboa.system.dao.RoleDAO.select(RoleDAO.java:409)
SELECT * FROM Role WHERE 1=1 order by createDate desc

 
配置文件的例子:

log4j.rootLogger=DEBUG
#将DAO层log记录到DAOLog,allLog中
log4j.logger.DAO=DEBUG,A2,A4
#将逻辑层log记录到BusinessLog,allLog中
log4j.logger.Businesslog=DEBUG,A3,A4

#A1--打印到屏幕上
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-5p [%t] %37c %3x - %m%n

#A2--打印到文件DAOLog中--专门为DAO层服务
log4j.appender.A2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A2.file=DAOLog
log4j.appender.A2.DatePattern='.'yyyy-MM-dd
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

#A3--打印到文件BusinessLog中--专门记录逻辑处理层服务log信息
log4j.appender.A3=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A3.file=BusinessLog
log4j.appender.A3.DatePattern='.'yyyy-MM-dd
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

#A4--打印到文件alllog中--记录所有log信息
log4j.appender.A4=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A4.file=alllog
log4j.appender.A4.DatePattern='.'yyyy-MM-dd
log4j.appender.A4.layout=org.apache.log4j.PatternLayout
log4j.appender.A4.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS}
method:%l%n%m%n

-----------------------------------------------
log4j.appender.Root=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Root.File=../logs/blog
log4j.appender.Root.DatePattern='_'yyyy-MM-dd'.log'
log4j.appender.Root.layout=org.apache.log4j.PatternLayout 
log4j.appender.Root.layout.ConversionPattern=[%p] %-d{yyyy-MM-dd HH\:mm\:ss} [%c.%M\:%L]  %m%n

这样的方式可以在tomcat/logs/ 下生成 如:blog_2009_11_12.log这样的log文件,网上都是这样说的,但实际上自己做的时候发现生成的老是  blog这样一个文件  没后缀,本以为会生成blog_2009_11_12.log这样的,怎么试都不对,快郁闷死了,后来改了一下我的电脑的时间,改到13号,发现这时生成了一个blog_2009_11_12.log

后来试了下,总算明白了 log4j会先生成blog这样一个文件,然后当这一天过去的时候,生成一个新的blog,然后把原来的保存为加上日期格式后缀的文件

----------------------------------------------------
将JBOSS4下的项目Log日志输到其它文件中
如果不进行优化配置,JBOSS下的项目查错将非常麻烦,在JBOSS4.2.2GA版本中,默认将所有的DEBUG信息都输了个遍,刚运行JBOSS,Server.log的日志就差不多1M了,再停掉JBOSS,什么正事都没做,都己经生成看不到的LOG了,只能用一个字来形容:费物!

  不过话先别说得这么激,年轻人,应该控制好自己的心态,冲动是魔兽咧!LOG太多确实一点用也没有,本来这些LOG最大的功能是方便查错的,但如果生成N行的LOG,从中找到你想要的,我还不如把程序检查一遍算了!因此,在不同的应用场合下,配置好你的LOG,才能让项目更加顺利地进行哦!

  好了,转入正题,本文针对的是JBOSS4的LOG4J配置,其它的请参阅相应的文章。

  JBOSS4的LOG4J配置默认放在Deploy目录的conf/目录下,比如现在我将ear放到jboss的default目录下,那么log4j的文件就是jboss/server/default/conf/jboss-log4j.xml,找到它,我们再分析一下它里面的内容吧。

  首先是第一段,一个FILE的appender,代码如下

Xml代码  <!-- A time/date based rolling appender --> 
   <appender name="FILE" > 
      <errorHandler /> 
      <param name="File" value="${jboss.server.log.dir}/server.log"/> 
      <param name="Append" value="false"/> 
 
      <!-- Rollover at midnight each day --> 
      <param name="DatePattern" value="'.'yyyy-MM-dd"/> 
 
      <!-- Rollover at the top of each hour 
      <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/> 
      --> 
 
      <layout > 
         <!-- The default pattern: Date Priority [Category] Message\n --> 
         <param name="ConversionPattern" value="%d %-5p [%c] %m%n"/> 
 
         <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n 
         <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/> 
          --> 
      </layout> 
   </appender> 



      上面这一段就是JBOSS默认输出到log/server.log文件的基本配置,它的name是FILE,这是自己定的,在其它地方会用这引name引用到它,然后appender的类型是DailyRollingFileAppender,意思是每天生成一个新的server.log文件,此时有人就会问,怎么每天都是server.log,那么昨天的岂不覆盖掉了?别担心,这种事情开发者早就想到了,它里面会有一些参数去设置它,自动让你前一天的log改其它名,当然appender的类型还有好几种,本文最后面有参考,根据你的项目的需要去设置它。

  中间第一个参数是log文件的输出地址,大家明白的了,改动一下就行了。

  第二个参数<param name="Append" value="false"/>,意思是运行jboss时,要不要覆盖之前的log,这在开发调试时很有用,你设成false后,每次你重新运行jboss,新生成的log都覆盖了旧的,这样找起来比较方便,也不用自己专门去删除它,但如果是正式使用了,可以根据需要将成设成true,这样所有的日志都会被保存起来了,隔一段时间,你就可以找到之前任一时候的log信息哦。

  上面讲到了有一些参数设置文件换前一天的log的文件名的,大家可以注意到配置的中间有个DatePattern,这个就是设置你前一天的log将会被改成什么名,它在每天晚上的午夜进行,很自动吧,你看它后面的'.'yyyy-MM-dd,你就会知道前一天的log的文件名将会被换成什么样的了!这里不进行填鸭!它还可以表现得更狠一下,每小时生成一个log怎么样,你想怎么样就怎么样,学学去配它吧。

  再往下,有一个PatternLayout,这个是输出文本的样式,这个是文本的,不过它还有得换哦,可以换成网页形式的日志(看起来会爽点),还有另外几个,大家有空可以玩玩,不过这个PatternLayout是最常用,也是最专业的,想成为专业人士,就用它吧!呵呵,开玩笑的,其它几个也很专业,甚至更专业!

  刚接触log4j的人会不太理解PatternLayout的作用,不过你用过之后,就知它是多么强悍的了,日志显示的形式随你心意改变,可以输出很多信息,如类名,类行号,详细时间,日志正文,还有日志级别等,如果你自己开发一个log工具,你会做到这么强吗?我以前做过一个,只能硬编码,其它什么都不能干,用了它,准会把你气死一半。我就气了三分之一,因为我写的嘛,呵呵,亲生的,不能什么都怪它,那怪谁。。。

  再往下有个ConversionPattern的参数,它是配置log的显示格式的,它的详细格式使用在本文后面会贴出,有需要就去看看,不过用它默认的都挺好的了。



  好了,之前介绍了一个默认的FILE Appender,还有一个CONSOLE的Appender,不用介绍了吧,就是显示在jboss控制台的日志样式,在此我们就不详谈了。

  徐了这两个默认的,还可以自定义Appender哦,比如你项目有不同类型的日志输出到不同的log日志中,或者你不想改动默认的log配置,另找高明,反正就是很个性化啦,生成多少个不同的log都行!

  在这里我拷贝了一个FILE的的appender,然后作了小小改动,就可以生成我自定义的log了,代码如下

Xml代码  <!-- A time/date based rolling appender --> 
<appender name="MYAPPENDER" > 
   <errorHandler /> 
   <param name="File" value="${jboss.server.log.dir}/mylog.log"/> 
   <param name="Append" value="false"/> 
 
   <!-- Rollover at midnight each day --> 
   <param name="DatePattern" value="'.'yyyy-MM-dd"/> 
 
   <!-- Rollover at the top of each hour 
   <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/> 
   --> 
 
   <layout > 
      <!-- The default pattern: Date Priority [Category] Message\n --> 
      <!--<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>--> 
 
      <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n--> 
      <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/> 
        
   </layout> 
</appender> 



  它将会在log目录生成一个mylog.log文件,不过有一点需要注意,在没有其它代码引用这些appender之前,它什么也不会干的,怎么引用还得往下看。

在jboss-log4j.xml文件里靠下的地方,有很多下面这类代码

Xml代码  <!-- Limit the org.jboss category to INFO as its DEBUG is verbose --> 
<category name="org.jboss"> 
   <priority value="INFO" /> 
</category> 



它是干嘛用的?它就是log4j的强悍之一,它检测到是org.jboss输出的信息的话,就限制DEBUG的信息输出,之前说过jboss的log信息超多,因为它默认将所有Debug信息都输出来了,这些jboss的debug信息对于我们这些平民百姓来说,没啥用,你加上我上面这一段,所有的JBOSS DEBUG信息都不会输出来的了,试试吧,其它的category你怎么改?讲一个我的经验给你们吧,你运行过jboss,然后停掉它,打开server.log,会看到很多的log信息,像下面这种

2008-10-18 16:00:59,203 DEBUG[org.apache.resource.deployment.RARDeployment] Required license terms exist, view META-INF/ra.xml in .../deploy/jboss-ha-local-jdbc.rar

看上面粗体部份,它是由类org.apache.resource.deployment.RARDeployment产生的log,你如果看到很多,你觉得没用,又或者你看到是DEBUG信息,你也不想要,就写一段category吧,将类的前面部分截取一段,写进category的name属性里,比如上面这类log,你不想看到它,你就这样写

Xml代码  <!-- Limit the org.apache category to INFO as its DEBUG is verbose --> 
<category name="org.apache"> 
   <priority value="INFO" /> 
</category> 



这样所有org.apache属下的类的debug log都不会再输出来了,你还可以更狠一点,写下面这段
 

Xml代码  <category name="org.apache"> 
      <priority value="ERROR" /> 
</category> 



  这样org.apache下的普通INFO信息也不会输出了,只有错误的信息才会被输出!

  至于其它的log信息,你就运行多几次jboss,每次根据server.log,找到你不想要的,再加多一些category,这样你的server.log就会变得非常精简的了,试试吧,一劳永逸,以后log就有得控制了,调试查错也更方便了。



  到了这里,事情还没完呢,最后一点了。

  之前我们自定义了一个appender,我们要用它来输出自己的项目的log,我们只是定义好了这个appender,还没用上它,它暂时还是不会起作用的(它会生成文件,但是没log往里面写),项目的log,还是只会在server.log里出现,不会写进你自定义的log里。下面我们干最后一点,完成所有工作。

  写多一个category,name填上自己项目对应的,比如com.mycompany,然后在<priority value="xxx" />后面加多一行<appender-ref ref="MYAPPENDER" />,如下

Xml代码  <!-- Self Define Appender --> 
   <category name="com.mycompany"> 
      <priority value="INFO" /> 
      <appender-ref ref="MYAPPENDER"/> 
   </category> 



配置好了,下面贴一段代码中使用log的代码中,怎么用不讲了,很简单的,



Java代码  public class TestLog4j 

    public static void main(String[] args)  
    { 
        Logger logger = Logger.getLogger(TestLog4j. class); 
        logger.debug( " debug " ); 
        logger.error( " error " ); 
        logger.info("info"); 
    }  
}  







  下面,贴出一些常用的配置参考文档

1\日志输出级别,共有5级:

FATAL       0 
ERROR      3 
WARN       4 
INFO         6 
DEBUG      7

2\Log4j提供的appender有以下几种:

org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

3\Log4j提供的layout有以下几种:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

4\Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,如下:
%m   输出代码中指定的消息
%p   输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r   输出自应用启动到输出该log信息耗费的毫秒数
%c   输出所属的类目,通常就是所在类的全名
%t   输出产生该日志事件的线程名
%n   输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
%d   输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},输出类似:2002年10月18日  22 : 10 : 28 , 921 
%l   输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java: 10 )

http://blog.csdn.net/shine0181/article/details/6632479

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- 设置通道ID:wapstdout和输出方式:org.apache.log4j.DailyRollingFileAppender -->
	<!-- DailyRollingFileAppender 每天产生一个日志文件 -->
	<!-- 配置输出目的地Appender Appender主要定义日志信息输出在什么位置 -->
	<appender name="wapstdout" >
		<param name="File" value="${catalina.base}/logs/fuxi/wap_stdout.log" />
		<!-- 日志文件时间后缀 -->
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<!-- 输出文本的样式 -->
		<layout >
			<!-- log的显示格式 -->
			<param name="ConversionPattern" value="%d{yyyy-MM-dd-HH:mm:ss,SSS}  %5p  - %m%n">
		</layout>
	</appender>

	<!-- 设置域名限制,即wap404logger域及以下的日志均输出到下面对应的通道中 --> 
	<logger name="wap404logger" additivity="false">
		<!-- 设置级别 -->
		<level value="info" />
		<!-- 与前面的通道id相对应 -->
		<appender-ref ref="wap404log" />
	</logger>
	<!-- 设置接收所有输出的通道 --> 
	<root>
		<level value="error" />
		<!-- 与前面的通道id相对应  -->
		<appender-ref ref="stdout" />
	</root>

</log4j:configuration>





    
[2] 一部分项目工程配置文件的说明
    来源: 互联网  发布时间: 2014-02-18
部分项目工程配置文件的说明
1、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<!-- 工具编辑部署描述符,display-name元素包含的就是XML编辑器显示的名称 -->
    <display-name>Archetype Created wqo Web Application</display-name>
    <!--
		Spring ApplicationContext配置文件的路径,可使用通配符,多个路径用,号分隔
		此参数用于后面的Spring-Context loader
	-->
	<context-param>
		<param-name>contextCongfigLocation</param-name>
		<param-value>
			classpath*:spring/*.xml
		</param-value>
	</context-param>
	<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>/WEB-INF/classes/log4j.xml</param-value>
	</context-param>
	
	<!-- ContextLoaderListener预设会读取applicationContext.xml,
	您可以指定自己的定义档,只要在<context-param>中指定"contextConfigLocation"参数 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- Log4jConfigListener 允许您通过 log4jConfigLocation Servlet 
	上下文参数显式指定 Log4J 配置文件的地址 -->
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
	
	<!-- 所有filter,委托给spring -->
	<filter>
		<filter-name>appFilters</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>appFilters</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<filter>
		<filter-name>etagFilter</filter-name>
		<filter-class>org.springframework.web.filter.ShallowEtagHeaderFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>etagFilter</filter-name>
		<servlet-name>/*</servlet-name>
	</filter-mapping>
	
	<servlet>
		<servlet-name>rest</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				<!-- 配置文件名 -->
				/WEB-INF/rest-servlet.xml,
				/WEB-INF/interceptor-servlet.xml,
				/WEB-INF/controller-servlet.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>rest</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<session-config>
		<session-timeout>1000</session-timeout>
	</session-config>
	
	<!-- 错误页面定义 -->
	<error-page>
		<error-code>404</error-code>
		<location>/WEB-INF/jsp/404.jsp</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/WEB-INF/jsp/500.jsp</location>
	</error-page>
	
</web-app>


2、rest-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
	xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
		
		<bean id="propertyConfigurer" 
			>
			<property name="locations">
				<list>
					<value>classpath*:config/*.properties</value>	
				</list>
			</property>
		</bean>
		
		<!-- Default View Resolver -->
		<bean id="internalResourceViewResolver"
			>
			<property name="order" value="1"/>
			<property name="prefix" value="/WEB-INF/jsp/"/>
			<property name="suffix" value=".jsp"/>
		</bean>
		
		<!-- jackson专门的视图MappingJacksonJsonView配置,完成转换json -->
		<bean id="jsonView" 
			>
			<property name="encoding">
				<value type="org.codehaus.jackson.JsonEncoding">UTF8</value>
			</property>
			<property name="contentType" value="application/json;charset=UTF-8" />
		</bean>
		
		<!-- 实现类似拦截器的功能 -->
		<bean id="hostUserArgumentResolver"  />
		
		<!-- 实现RESTful URL映射,为了实现方法级别的注解,就需要确保DefaultAnnotationHandlerMapping
		和AnnotationMethodHandlerAdapter同时被定义 -->
		<bean 
			>
			<property name="customArgumentResolver" ref="hostUserArgumentResolver" />
			<property name="messageConverters">
				<util:list id="beanList">
					<ref bean="mappingJacksonHttpMessageConverter" />
				</util:list>
			</property>	
		</bean>
		
		<!-- 能够将POJO对象自动转换为JSON对象 -->
		<bean id="mappingJacksonHttpMessageConverter"
			 />

		<!-- url mapping by bean name  实现类型级别的注解-->
		<bean id="handlerMapping"
			>
			<property name="order" value="0" />
		</bean>
		
		<!-- Default ExceptionHandler -->
		<bean id="defaultExceptionHandler" >
			<property name="defaultErrorView" value="error" />
			<property name="defaultStatusCode" value="500" />
		</bean>
		

</beans>


3、interceptor-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
	xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">


	<!-- 会为每一个HandlerMapping,注入一个拦截器 ,起到总拦截器的作用-->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean />
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean  />
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean  />
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean  />
		</mvc:interceptor>
	</mvc:interceptors>
	
</beans>


4、log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- 设置通道ID:wapstdout和输出方式:org.apache.log4j.DailyRollingFileAppender -->
	<!-- DailyRollingFileAppender 每天产生一个日志文件 -->
	<!-- 配置输出目的地Appender Appender主要定义日志信息输出在什么位置 -->
	<appender name="wapstdout" >
		<param name="File" value="${catalina.base}/logs/fuxi/wap_stdout.log" />
		<!-- 日志文件时间后缀 -->
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<!-- 输出文本的样式 -->
		<layout >
			<!-- log的显示格式 -->
			<param name="ConversionPattern" value="%d{yyyy-MM-dd-HH:mm:ss,SSS}  %5p  - %m%n">
		</layout>
	</appender>

	<appender name="stdout" >
		<param name="File" value="${catalina.base}/logs/fuxi/stdout.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout >
			<param name="ConversionPattern" value="%d{yyyy-MM-dd-HH:mm:ss,SSS} %5p   - %m%n" />
		</layout>
	</appender>

	<appender name="wap404log" >
		<param name="File" value="${catalina.base}/logs/fuxi/wap404.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout >
			<param name="ConversionPattern" value="%d{yyyy-MM-dd-HH:mm:ss,SSS} %5p   - %m%n" />
		</layout>
	</appender>

	<appender name="wap500log" >
		<param name="File" value="${catalina.base}/logs/fuxi/wap500.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout >
			<param name="ConversionPattern" value="%d{yyyy-MM-dd-HH:mm:ss,SSS} %5p   - %m%n" />
		</layout>
	</appender>

	<appender name="useraccessLogAppender" >
		<param name="File" value="${catalina.base}/logs/fuxi/useraccess.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd_HH" />
		<layout >
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>

	<appender name="useraccessRemoteLogAppender"
		>
		<param name="iceArgs" value="WapRemoteLogger2:tcp -h 10.3.19.155 -p 10000" />
		<param name="remoteLoggerName" value="fuxi_useraccess" />
		<layout >
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>
	
	<appender name="useractionLogAppender" >
		<param name="File" value="${catalina.base}/logs/fuxi/useraction.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd_HH" />
		<layout >
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>
	
	<appender name="useractionRemoteLogAppender"
		>
		<param name="iceArgs" value="WapRemoteLogger2:tcp -h 10.3.19.155 -p 10000" />
		<param name="remoteLoggerName" value="fuxi_useraction" />
		<layout >
			<param name="ConversionPattern" value="%m%n" />
		</layout>
	</appender>

	<!-- 设置域名限制,即wap404logger域及以下的日志均输出到下面对应的通道中 --> 
	<logger name="wap404logger" additivity="false">
		<!-- 设置级别 -->
		<level value="info" />
		<!-- 与前面的通道id相对应 -->
		<appender-ref ref="wap404log" />
	</logger>

	<logger name="wap500logger" additivity="false">
		<level value="info" />
		<appender-ref ref="wap500log" />
	</logger>
	
	<logger name="useraccessLogger" additivity="false">
		<level value="info" />
		<appender-ref ref="useraccessLogAppender" />
	</logger>
	
	<logger name="useraccessRemoteLogger" additivity="false">
		<level value="info" />
		<appender-ref ref="useraccessRemoteLogAppender" />
	</logger>
	
	<logger name="localuseraction" additivity="false">
		<level value="info" />
		<appender-ref ref="useractionLogAppender" />
	</logger>
	
	<logger name="useraction" additivity="false">
		<level value="info" />
		<appender-ref ref="useractionRemoteLogAppender" />
	</logger>

	<logger name="org.springframework" additivity="false">
		<level value="error" />
		<appender-ref ref="stdout" />
	</logger>

	<logger name="com.renren.wap.fuxi" additivity="false">
		<level value="debug" />
		<appender-ref ref="wapstdout" />
	</logger>

	<logger name="com.xiaonei" additivity="false">
		<level value="error" />
		<appender-ref ref="wapstdout" />
	</logger>
	
	<!-- 设置接收所有输出的通道 --> 
	<root>
		<level value="error" />
		<!-- 与前面的通道id相对应  -->
		<appender-ref ref="stdout" />
	</root>

</log4j:configuration>

    
[3] 电池及充电相干的服务BatteryService的实现
    来源: 互联网  发布时间: 2014-02-18
电池及充电相关的服务BatteryService的实现
BatteryService作为电池及充电相关的服务,它的实现非常简单:

o 监听UEvent,读取sysfs里中的状态。

实现了一个UEvent的观察者。uevent是Linux内核用来向用户空间主动上报事件的机制,对于JAVA程序来说,只实现UEventObserver的虚函数onUEvent,然后注册即可。

    private UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
            update();
        }
    };

这里只关注power_supply的事件:

mUEventObserver.startObserving("SUBSYSTEM=power_supply");

当有power_supply相关的事件上报时,就会调用update函数。

update先调用native_update从sysfs中读取相关状态(com_android_server_BatteryService.cpp),
"native_update"=>android_server_BatteryService_update:

Linux驱动提供了下列文件,供应用程序获取电源相关状态:

#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"
#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"
#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"
#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"
#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"
#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"
#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"
#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"
#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"

在<DA9034驱动程序阅读笔记(6)>一文中,我已经提到drivers/power /micco_power.c里注册了充电器(ac)、 usb和电池(battery)三个power_supply。各个power_supply提供的属性和上述文件是对应的,从这些文件中可以读到充电器 (ac)、usb和电池(battery)三个power_supply的相应状态。

update然后根据读到的状态更新BatteryService的成员变量,并广播一个 Intent来通知其它关注电源状态的组件。

    private final void sendIntent() {
        //  Pack up the values and broadcast them to everyone
        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        try {
            mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel);
        } catch (RemoteException e) {
            // Should never happen.
        }

        int icon = getIcon(mBatteryLevel);

        intent.putExtra("status", mBatteryStatus);
        intent.putExtra("health", mBatteryHealth);
        intent.putExtra("present", mBatteryPresent);
        intent.putExtra("level", mBatteryLevel);
        intent.putExtra("scale", BATTERY_SCALE);
        intent.putExtra("icon-small", icon);
        intent.putExtra("plugged", mPlugType);
        intent.putExtra("voltage", mBatteryVoltage);
        intent.putExtra("temperature", mBatteryTemperature);
        intent.putExtra("technology", mBatteryTechnology);

        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }

关注ACTION_BATTERY_CHANGED的地方有好几个:

o KeyguardUpdateMonitor 这里主要是用来更新锁屏界面下的电池状态。还有低电警告和关机也是在这里做的。

    private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) {
        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
        final boolean pluggedIn = isPluggedIn(pluggedInStatus);

        if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) {
            mBatteryLevel = batteryLevel;
            mDevicePluggedIn = pluggedIn;
            for (int i = 0; i < mInfoCallbacks.size(); i++) {
                mInfoCallbacks.get(i).onRefreshBatteryInfo(
                        shouldShowBatteryInfo(), pluggedIn, batteryLevel);
            }
        }

        // shut down gracefully if our battery is critically low and we are not powered
        if (batteryLevel == 0 &&
                pluggedInStatus != BATTERY_STATUS_CHARGING &&
                pluggedInStatus != BATTERY_STATUS_UNKNOWN) {

            ShutdownThread.shutdownAfterDisablingRadio(mContext, false);

        }
    }

o NotificationManagerService 用来更新充电状态(LED)

            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                boolean batteryCharging = (intent.getIntExtra("plugged", 0) != 0);
                int level = intent.getIntExtra("level", -1);
                boolean batteryLow = (level >= 0 && level <= Power.LOW_BATTERY_THRESHOLD);
                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
                boolean batteryFull = (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90);

                if (batteryCharging != mBatteryCharging ||
                        batteryLow != mBatteryLow ||
                        batteryFull != mBatteryFull) {
                    mBatteryCharging = batteryCharging;
                    mBatteryLow = batteryLow;
                    mBatteryFull = batteryFull;
                    updateLights();
                }
            }

o PowerManagerService 这里主要是做两件事件,先是检查是否在充电时不允许睡眠,并采用相应的行动,其次是触发一个用户行为(会影响下一次睡眠的时间)。

    private final class BatteryReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLocks) {
                boolean wasPowered = mIsPowered;
                mIsPowered = mBatteryService.isPowered();

                if (mIsPowered != wasPowered) {
                    // update mStayOnWhilePluggedIn wake lock
                    updateWakeLockLocked();

                    // treat plugging and unplugging the devices as a user activity.
                    // users find it disconcerting when they unplug the device
                    // and it shuts off right away.
                    // temporarily set mUserActivityAllowed to true so this will work
                    // even when the keyguard is on.
                    synchronized (mLocks) {
                        boolean savedActivityAllowed = mUserActivityAllowed;
                        mUserActivityAllowed = true;
                        userActivity(SystemClock.uptimeMillis(), false);
                        mUserActivityAllowed = savedActivityAllowed;
                    }
                }
            }
        }
    }

o LocationManagerService 这里似乎没有什么用处,我没找到mCollector赋值的地方。

             if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                log("PowerStateBroadcastReceiver: Battery changed");
                synchronized (mLocationListeners) {
                    int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
                    int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
                    boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;

                    // Notify collector battery state
                    if (mCollector != null) {
                        mCollector.updateBatteryState(scale, level, plugged);
                    }
                }
            }

o WifiService 根据电源状态来决定是否需要定时唤醒(没搞得太明白,看Wifi服务时再研究)。

if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                /*
                 * Set a timer to put Wi-Fi to sleep, but only if the screen is off
                 * AND we are transitioning from a state in which the device was supposed
                 * to stay awake to a state in which it is not supposed to stay awake.
                 * If "stay awake" state is not changing, we do nothing, to avoid resetting
                 * the already-set timer.
                 */
                int pluggedType = intent.getIntExtra("plugged", 0);
                if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
                        !shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
                    long triggerTime = System.currentTimeMillis() + idleMillis;
                    mAlARMManager.set(AlARMManager.RTC_WAKEUP, triggerTime, mIdleIntent);
                    mPluggedType = pluggedType;
                    return;
                }
                mPluggedType = pluggedType;
            }

o StatusBarPolicy用来更新状态栏上的充电图标。

if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                updateBattery(intent);
            }

一、BATTERY相关广播

1.Intent.ACTION_BATTERY_CHANGED  电量状态更新

包括下面的信息。

    “status”(int类型)…状态,定义值是BatteryManager.BATTERY_STATUS_XXX。

    “health”(int类型)…健康,定义值是BatteryManager.BATTERY_HEALTH_XXX。

    “present”(boolean类型)

    “level”(int类型)…电池剩余容量

    “scale”(int类型)…电池最大值。通常为100。

    “icon-small”(int类型)…图标ID。

    “plugged”(int类型)…连接的电源插座,定义值是BatteryManager.BATTERY_PLUGGED_XXX。

    “voltage”(int类型)…mV。

    “temperature”(int类型)…温度,0.1度单位。例如 表示197的时候,意思为19.7度。 

    “technology”(String类型)…电池类型,例如,Li-ion等等。



2.Intent.ACTION_BATTERY_LOW  //表示电池电量低

3.Intent.ACTION_BATTERY_OKAY  //表示电池电量充足,即从电池电量低变化到饱满时会发出广播



二、监听UEventObserver,读取sysfs里中的状态

private UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
           String strOnline = event.get("POWER_SUPPLY_ONLINE");   //电源连接状态
           String strBatteryState = event.get("POWER_SUPPLY_STATUS");  

                                        //电池状态,"Discharging","Charging","Not charging","Full","Unknown"
           String strBatteryLevel = event.get("POWER_SUPPLY_CAPACITY");   //电池剩余容量

           ...

        }

  }

1.BatteryService通过JNI(com_android_server_BatteryService.cpp)读取数据。BatteryService通过JNI注册的不仅有函数,还有变量。 如下:
  //##############在BatteryService.java中声明的变量################
  private boolean mAcOnline;
    private boolean mUsbOnline;
  private int mBatteryStatus;
  private int mBatteryHealth;
  private boolean mBatteryPresent;
  private int mBatteryLevel;
  private int mBatteryVoltage;
  private int mBatteryTemperature;
  private String mBatteryTechnology;

2.在BatteryService.java中声明的变量,在com_android_server_BatteryService.cpp 中共用,即在com_android_server_BatteryService.cpp中其实操作的也是BatteryService.java中声明的变量
  gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
  gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
  gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
  gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
  gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
  gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
  gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");
  gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");
    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");

3.上面这些变量的值,对应是从下面的文件中读取的,一个文件存储一个数值。
    #define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"     AC电源连接状态
    #define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"   USB电源连接状态
  #define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"    充电状态
  #define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"     电池状态
  #define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"   使用状态
  #define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"   电池level
  #define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"    电池电压
  #define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"   电池温度
  #define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"   电池技术


android\kernel\kernel\drivers\power\88pm860x_battery.c
pm860x_changed_work
struct pm860x_battery_info *info = container_of(work,
  struct pm860x_battery_info, changed_work.work);

pm860x_update_charge_state(info);

power_supply_changed(&info->battery);
MONITOR_INTERVAL

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3