Androidpn client的运行步骤
创建ServiceManger对象,设置提醒时候的图标
1) 读取raw下的andriodpn.properties信息,apikey、xmppHost、xmppPort
2) 创建client_preferences.xml 并存入信息apikey、xmppHost、xmppPort、version、CALLBACK_ACTIVITY_CLASS_NAME、CALLBACK_ACTIVITY_PACKAGE_NAME 信息
开启服务
1) 创建serviceThread线程,
2) 在线程中通过开始NotificationService服务(推送的后台服务)
在NotificationService创建时onCreate()
1) 创建出电话管理器TelephonyManager 获取手机的deviceId,存入client_preference中去
2) 如果手机是模拟器则deviceId的值变成0+,并且多加上EMULATOR_DEVICE_ID属性
3) 创建XmppManager对象
4) 提交一个线程任务(TaskSubmitter.submit) ß
5) 任务内容为(NotificationService.start()),注册广播事件NotificationReceiver和ConnectivityReceiver 、调用xmpp进行连接
a) NotificationReceiver 进行推送过来的数据封装,传给notifier这时就可以看到推送的消息了,数据有(id、api_key、title、message、url)
ConnectivityReceiver 通过ConnectivityManager判断是否有网络,如果有网络进进行notificationService.connect() 实际上xmpp的连接,如果没网络就销毁连接notificationService.discount()
6)
4. XmppManager的xmpp的连接
1) 添加连接任务ConnectTask 到线程池中
2) 添加注册任务RegisterTask到线程池中
如果在client_preferences中没有找到用户名密码,就随机生成一个用户名密码向服务器注册
发送
<iq id="3XeCX-0" type="set">
<query xmlns="jabber:iq:register">
<password>8760a685a5b44132b9f86357cac6fcd5</password>
<username> d93db873c4fa4858a7a562e08537f6bf </username>
</query>
</iq>
接受
<iq type="result" id="3XeCX-0" to="127.0.0.1/1868b569" />
添加登录任务LoginTask到线程池中
先判断是否有权限(此账户是否登录已经登录)
发送
<iq id="DUE1S-0" type="get">
<query xmlns="jabber:iq:auth">
<username>d93db873c4fa4858a7a562e08537f6bf</username>
</query>
</iq>
接受:
<iq type="result" id="DUE1S-0">
<query xmlns="jabber:iq:auth">
<username>d93db873c4fa4858a7a562e08537f6bf</username>
<password />
<digest />
<resource />
</query>
</iq>
如果没有登录发送xml信息:
<iq id="DUE1S-1" type="set">
<query xmlns="jabber:iq:auth">
<username>d93db873c4fa4858a7a562e08537f6bf</username>
<digest>36926a5756f65910b1be819346dbc827883425b4</digest>
<resource>AndroidpnClient</resource>
</query>
</iq>
接受消息的格式
<iq type="set" id="214-0" to="a64e0a7d27a94d3a9760b77d10223ccc@127.0.0.1/AndroidpnClient">
<notification xmlns="androidpn:iq:notification">
<id>1eb0f3ed</id>
<apiKey>1234567890</apiKey>
<title>title11</title>
<message>msg22</message>
<uri>http://www.baidu.com</uri>
</notification>
</iq>
如果登录时没有注册会抛出XMPPException异常,异常码为401;会清除client_preference中的username和password数据
登录之后,会有一个NotificationPacketListener心跳包监听器在后台运行,只要监听到有数据包发送过来就会通过NotificationIQProvider对NotificationIQ进行解析,并且发送广播给NotificationReceiver
androidpn server启动步骤
androidpn (Android Push Notification)是一个基于XMPP协议的java开源Android push notification实现。
它包含了完整的客户端和服务器端。
本文是在Tomcat下部署 androidpn server的启动日志的分析。
# tail -f logs/catalina.out
#启动Tomcat的服务:对应tomcat/conf/server.xml中的 <Service name="Catalina">
May 04, 2014 2:55:59 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
#启动 Tomcat servlet 引擎:对应 tomcat/conf/server.xml中的 <Engine name="Catalina" defaultHost="localhost">
May 04, 2014 2:55:59 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.39
#部署ROOT目录
May 04, 2014 2:56:03 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory /app/apache-tomcat-7.0.39/webapps/ROOT
#验证jar包
May 04, 2014 2:56:03 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/app/apache-tomcat-7.0.39/webapps/ROOT/WEB-INF/lib/el-api-6.0.29.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
May 04, 2014 2:56:03 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/app/apache-tomcat-7.0.39/webapps/ROOT/WEB-INF/lib/jsp-api-2.1.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/el/Expression.class
May 04, 2014 2:56:03 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(/app/apache-tomcat-7.0.39/webapps/ROOT/WEB-INF/lib/servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
#Spring ContextLoaderListener初始化开始
{INFO } [2014-05-04 14:56:04,977] <org.springframework.web.context.ContextLoader> : Root WebApplicationContext: initialization started
#使用 XmlWebApplicationContext ,XmlWebApplicationContext实现了WebApplicationContext接口,当前的servlet用它来创建上下文。
#如果之后还有其他继承的上下文的时候,这里创建的context作为内容上下文的根,称为 ROOT
#实际名称为 org.springframework.web.context.WebApplicationContext.ROOT
{INFO } [2014-05-04 14:56:05,001] <org.springframework.web.context.support.XmlWebApplicationContext> : Refreshing Root WebApplicationContext: startup date [Sun May 04 14:56:05 CST 2014]; root of context hierarchy
#开始加载web.xml 中 <context-param>标签 contextConfigLocation 配置的文件
{INFO } [2014-05-04 14:56:05,035] <org.springframework.beans.factory.xml.XmlBeanDefinitionReader> : Loading XML bean definitions from class path resource [conf/application-context.xml]
#开始加载 application-context.xml 中import引用的配置文件
{INFO } [2014-05-04 14:56:05,219] <org.springframework.beans.factory.xml.XmlBeanDefinitionReader> : Loading XML bean definitions from class path resource [conf/rest/rest-component-config.xml]
#IoC容器的实现类,列出所有的spring中配置的bean id,这些bean在 ROOT context上下文中
{INFO } [2014-05-04 14:56:05,326] <org.springframework.beans.factory.support.DefaultListableBeanFactory> : Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@14562294: defining beans [component,application,router,get,post]; root of factory hierarchy
#Spring ContextLoaderListener初始化完成
{INFO } [2014-05-04 14:56:05,408] <org.springframework.web.context.ContextLoader> : Root WebApplicationContext: initialization completed in 430 ms
#开始初始化 dispatcher
{INFO } [2014-05-04 14:56:05,446] <org.springframework.web.servlet.DispatcherServlet> : FrameworkServlet 'dispatcher': initialization started
#使用 XmlWebApplicationContext ,XmlWebApplicationContext实现了WebApplicationContext接口,当前的servlet用它来创建上下文。
#上级context上下文是 Root WebApplicationContext
{INFO } [2014-05-04 14:56:05,448] <org.springframework.web.context.support.XmlWebApplicationContext> : Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Sun May 04 14:56:05 CST 2014]; parent: Root WebApplicationContext
#加载 dispatcher-servlet.xml
{INFO } [2014-05-04 14:56:05,448] <org.springframework.beans.factory.xml.XmlBeanDefinitionReader> : Loading XML bean definitions from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]
#IoC容器的实现类,列出所有的dispatcher-servlet中配置的bean id,上级的Ioc容器是在Spring中创建的。
{INFO } [2014-05-04 14:56:05,500] <org.springframework.beans.factory.support.DefaultListableBeanFactory> : Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2604a07d: defining beans [urlMapping,filenameController,userController,sessionController,notificationController,paramResolver,viewResolver,messageSource]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@14562294
#发现NotificationController中的方法
{DEBUG} [2014-05-04 14:56:05,526] <org.androidpn.server.console.controller.NotificationController> : Found action method [public org.springframework.web.servlet.ModelAndView org.androidpn.server.console.controller.NotificationController.send(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
{DEBUG} [2014-05-04 14:56:05,526] <org.androidpn.server.console.controller.NotificationController> : Found action method [public org.springframework.web.servlet.ModelAndView org.androidpn.server.console.controller.NotificationController.list(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
#此处实例化NotificationController ,调用 NotificationController 的无参数构造方法。
#NotificationController无参构造方法实例化 NotificationManager
#NotificationManager无参构造方法实例化 SessionManager
#SessionManager无参数构造方法实例化 XmppServer
#XmppServer 无参构造方法实例化并调用start()方法,初始化服务的路径读取配置文件.
#通过 Config 代理并实例化 ConfigManager 加载 config.xml 。
{DEBUG} [2014-05-04 14:56:05,580] <org.apache.commons.configuration.ConfigurationUtils> : ConfigurationUtils.locate(): base is /app/apache-tomcat-7.0.39, name is config.xml
{DEBUG} [2014-05-04 14:56:05,596] <org.apache.commons.configuration.ConfigurationUtils> : Loading configuration from the context classpath (config.xml)
#加载 config.xml中的配置文件 config.properties
{DEBUG} [2014-05-04 14:56:05,693] <org.apache.commons.configuration.ConfigurationUtils> : ConfigurationUtils.locate(): base is /app/apache-tomcat-7.0.39, name is config.properties
{DEBUG} [2014-05-04 14:56:05,693] <org.apache.commons.configuration.ConfigurationUtils> : Loading configuration from the context classpath (config.properties)
#config.xml加载完毕
{INFO } [2014-05-04 14:56:05,702] <org.androidpn.server.util.ConfigManager> : Configuration loaded: config.xml
#用 ClassPathXmlApplicationContext 加载 spring-config.xml配置文件
{INFO } [2014-05-04 14:56:05,712] <org.springframework.context.support.ClassPathXmlApplicationContext> : Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@359d9606: startup date [Sun May 04 14:56:05 CST 2014]; root of context hierarchy
{INFO } [2014-05-04 14:56:05,713] <org.springframework.beans.factory.xml.XmlBeanDefinitionReader> : Loading XML bean definitions from class path resource [spring-config.xml]
#加载 spring-config.xml 文件中的 jdbc.properties 配置文件。
{INFO } [2014-05-04 14:56:05,813] <org.springframework.beans.factory.config.PropertyPlaceholderConfigurer> : Loading properties file from class path resource [jdbc.properties]
# MINA Socket 配置
{WARN } [2014-05-04 14:56:05,830] <org.springframework.beans.factory.config.CustomEditorConfigurer> : Passing PropertyEditor instances into CustomEditorConfigurer is deprecated: use PropertyEditorRegistrars or PropertyEditor class names instead. Offending key [java.net.SocketAddress; offending editor instance: org.apache.mina.integration.beans.InetSocketAddressEditor@67b7d0fb
# Ioc 列表Spring beans id
{INFO } [2014-05-04 14:56:05,838] <org.springframework.beans.factory.support.DefaultListableBeanFactory> : Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@243e2c21: defining beans [propertyConfigurer,dataSource,sessionFactory,transactionManager,userDao,userService,org.springframework.beans.factory.config.CustomEditorConfigurer#0,xmppHandler,filterChainBuilder,ioAcceptor]; root of factory hierarchy
(这里的Spring applicationContext 与前面的applicationContext没有任何关系,是独立的。两个上下文中的bean不可见,修改的方法见 http://blog.csdn.net/teamlet/article/details/26476671 )
#实例化beans
{INFO } [2014-05-04 14:56:05,928] <org.hibernate.cfg.annotations.Version> : Hibernate Annotations 3.4.0.GA
{INFO } [2014-05-04 14:56:05,936] <org.hibernate.cfg.Environment> : Hibernate 3.3.1.GA
{INFO } [2014-05-04 14:56:05,939] <org.hibernate.cfg.Environment> : hibernate.properties not found
{INFO } [2014-05-04 14:56:05,942] <org.hibernate.cfg.Environment> : Bytecode provider name : javassist
{INFO } [2014-05-04 14:56:05,945] <org.hibernate.cfg.Environment> : using JDK 1.4 java.sql.Timestamp handling
{INFO } [2014-05-04 14:56:06,020] <org.hibernate.annotations.common.Version> : Hibernate Commons Annotations 3.1.0.GA
{INFO } [2014-05-04 14:56:06,031] <org.hibernate.cfg.Configuration> : configuring from url: file:/data/apache-tomcat-7.0.39/webapps/ROOT/WEB-INF/classes/hibernate.cfg.xml
{INFO } [2014-05-04 14:56:06,122] <org.hibernate.cfg.Configuration> : Configured SessionFactory: null
{INFO } [2014-05-04 14:56:06,156] <org.hibernate.cfg.AnnotationBinder> : Binding entity from annotated class: org.androidpn.server.model.User
{INFO } [2014-05-04 14:56:06,184] <org.hibernate.cfg.annotations.EntityBinder> : Bind entity org.androidpn.server.model.User on table apn_user
{INFO } [2014-05-04 14:56:06,221] <org.hibernate.cfg.AnnotationConfiguration> : Hibernate Validator not found: ignoring
{INFO } [2014-05-04 14:56:06,222] <org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean> : Building new Hibernate SessionFactory
{INFO } [2014-05-04 14:56:06,224] <org.hibernate.cfg.search.HibernateSearchEventListenerRegister> : Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
{INFO } [2014-05-04 14:56:06,263] <org.hibernate.connection.ConnectionProviderFactory> : Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider
{INFO } [2014-05-04 14:56:06,439] <org.hibernate.cfg.SettingsFactory> : RDBMS: MySQL, version: 5.5.33-log
{INFO } [2014-05-04 14:56:06,439] <org.hibernate.cfg.SettingsFactory> : JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.1.6 ( Revision: ${svn.Revision} )
{INFO } [2014-05-04 14:56:06,449] <org.hibernate.dialect.Dialect> : Using dialect: org.hibernate.dialect.MySQLDialect
{INFO } [2014-05-04 14:56:06,452] <org.hibernate.transaction.TransactionFactoryFactory> : Transaction strategy: org.springframework.orm.hibernate3.SpringTransactionFactory
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.transaction.TransactionManagerLookupFactory> : No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.cfg.SettingsFactory> : Automatic flush during beforeCompletion(): disabled
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.cfg.SettingsFactory> : Automatic session close at end of transaction: disabled
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.cfg.SettingsFactory> : JDBC batch size: 15
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.cfg.SettingsFactory> : JDBC batch updates for versioned data: disabled
{INFO } [2014-05-04 14:56:06,453] <org.hibernate.cfg.SettingsFactory> : Scrollable result sets: enabled
{INFO } [2014-05-04 14:56:06,454] <org.hibernate.cfg.SettingsFactory> : JDBC3 getGeneratedKeys(): enabled
{INFO } [2014-05-04 14:56:06,454] <org.hibernate.cfg.SettingsFactory> : Connection release mode: auto
{INFO } [2014-05-04 14:56:06,454] <org.hibernate.cfg.SettingsFactory> : Maximum outer join fetch depth: 2
{INFO } [2014-05-04 14:56:06,454] <org.hibernate.cfg.SettingsFactory> : Default batch fetch size: 1
{INFO } [2014-05-04 14:56:06,454] <org.hibernate.cfg.SettingsFactory> : Generate SQL with comments: enabled
{INFO } [2014-05-04 14:56:06,455] <org.hibernate.cfg.SettingsFactory> : Order SQL updates by primary key: disabled
{INFO } [2014-05-04 14:56:06,455] <org.hibernate.cfg.SettingsFactory> : Order SQL inserts for batching: disabled
{INFO } [2014-05-04 14:56:06,455] <org.hibernate.cfg.SettingsFactory> : Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
{INFO } [2014-05-04 14:56:06,456] <org.hibernate.hql.ast.ASTQueryTranslatorFactory> : Using ASTQueryTranslatorFactory
{INFO } [2014-05-04 14:56:06,456] <org.hibernate.cfg.SettingsFactory> : Query language substitutions: {}
{INFO } [2014-05-04 14:56:06,456] <org.hibernate.cfg.SettingsFactory> : JPA-QL strict compliance: disabled
{INFO } [2014-05-04 14:56:06,456] <org.hibernate.cfg.SettingsFactory> : Second-level cache: enabled
{INFO } [2014-05-04 14:56:06,457] <org.hibernate.cfg.SettingsFactory> : Query cache: disabled
{INFO } [2014-05-04 14:56:06,460] <org.hibernate.cfg.SettingsFactory> : Cache region factory : org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge
{INFO } [2014-05-04 14:56:06,460] <org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge> : Cache provider: net.sf.ehcache.hibernate.EhCacheProvider
{INFO } [2014-05-04 14:56:06,462] <org.hibernate.cfg.SettingsFactory> : Optimize cache for minimal puts: disabled
{INFO } [2014-05-04 14:56:06,462] <org.hibernate.cfg.SettingsFactory> : Structured second-level cache entries: disabled
{INFO } [2014-05-04 14:56:06,465] <org.hibernate.cfg.SettingsFactory> : Echoing all SQL to stdout
{INFO } [2014-05-04 14:56:06,466] <org.hibernate.cfg.SettingsFactory> : Statistics: disabled
{INFO } [2014-05-04 14:56:06,466] <org.hibernate.cfg.SettingsFactory> : Deleted entity synthetic identifier rollback: disabled
{INFO } [2014-05-04 14:56:06,466] <org.hibernate.cfg.SettingsFactory> : Default entity-mode: pojo
{INFO } [2014-05-04 14:56:06,466] <org.hibernate.cfg.SettingsFactory> : Named query checking : enabled
{INFO } [2014-05-04 14:56:06,488] <org.hibernate.impl.SessionFactoryImpl> : building session factory
{INFO } [2014-05-04 14:56:06,659] <org.hibernate.impl.SessionFactoryObjectFactory> : Not binding factory to JNDI, no JNDI name configured
{INFO } [2014-05-04 14:56:06,664] <org.hibernate.tool.hbm2ddl.SchemaUpdate> : Running hbm2ddl schema update
{INFO } [2014-05-04 14:56:06,664] <org.hibernate.tool.hbm2ddl.SchemaUpdate> : fetching database metadata
{INFO } [2014-05-04 14:56:06,665] <org.hibernate.tool.hbm2ddl.SchemaUpdate> : updating schema
{INFO } [2014-05-04 14:56:06,678] <org.hibernate.tool.hbm2ddl.TableMetadata> : table found: apn.apn_user
{INFO } [2014-05-04 14:56:06,678] <org.hibernate.tool.hbm2ddl.TableMetadata> : columns: [created_date, id, username, updated_date, email, name, password]
{INFO } [2014-05-04 14:56:06,678] <org.hibernate.tool.hbm2ddl.TableMetadata> : foreign keys: []
{INFO } [2014-05-04 14:56:06,678] <org.hibernate.tool.hbm2ddl.TableMetadata> : indexes: [username, primary]
{INFO } [2014-05-04 14:56:06,679] <org.hibernate.tool.hbm2ddl.SchemaUpdate> : schema update complete
{INFO } [2014-05-04 14:56:06,703] <org.springframework.orm.hibernate3.HibernateTransactionManager> : Using DataSource [org.apache.commons.dbcp.BasicDataSource@588d16eb] of Hibernate SessionFactory for HibernateTransactionManager
{DEBUG} [2014-05-04 14:56:06,802] <org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder> : LinkedHashMap is an ordered map.
{INFO } [2014-05-04 14:56:06,836] <org.androidpn.server.xmpp.XmppServer> : Spring Configuration loaded.
{INFO } [2014-05-04 14:56:06,836] <org.androidpn.server.xmpp.XmppServer> : XmppServer started: 127.0.0.1
{INFO } [2014-05-04 14:56:06,836] <org.androidpn.server.xmpp.XmppServer> : Androidpn Server v0.5.0
{DEBUG} [2014-05-04 14:56:06,892] <org.androidpn.server.console.controller.UserController> : Found action method [public org.springframework.web.servlet.ModelAndView org.androidpn.server.console.controller.UserController.list(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
{DEBUG} [2014-05-04 14:56:06,906] <org.androidpn.server.console.controller.SessionController> : Found action method [public org.springframework.web.servlet.ModelAndView org.androidpn.server.console.controller.SessionController.list(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception]
# dispatcher 初始化完毕。
{INFO } [2014-05-04 14:56:06,937] <org.springframework.web.servlet.DispatcherServlet> : FrameworkServlet 'dispatcher': initialization completed in 1490 ms
# 对应 tomcat/conf/server.xml中的 Connector 8080端口
May 04, 2014 2:56:09 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
# 对应 tomcat/conf/server.xml中的 Connector 8009端口
May 04, 2014 2:56:09 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
# 对应 tomcat/conf/server.xml中的 Server
May 04, 2014 2:56:09 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 9459 ms
<启动完成>