smack 源码分析- PacketReader (android上实现长连接)【3】
smack 源码分析- PacketWriter (android上实现长连接)介绍完PacketWriter 之后, 接下来分析PacketReader.PacketReader的作用主要用来接收云端推送的消息并解析然后调用相应的监听器完成相关的操作.
什么都别说, 先看代码:
[java] view plain copy
- //构造函数
- protectedPacketReader(finalXMPPConnectionconnection){
- this.connection=connection;
- this.init();
- }
- /**
- *Initializesthereaderinordertobeused.Thereaderisinitialized
- *duringthefirstconnectionandwhenreconnectingduetoanabruptly
- *disconnection.
- */
- protectedvoidinit(){
- done=false;
- connectionID=null;
- //开辟一个线程,解析收到的数据包
- readerThread=newThread(){
- publicvoidrun(){
- parsePackets(this);
- }
- };
- readerThread.setName("SmackPacketReader("+connection.connectionCounterValue+")");
- readerThread.setDaemon(true);
- //Createanexecutortodeliverincomingpacketstolisteners.We'll
- //useasingle
- //threadwithanunboundedqueue.
- listenerExecutor=Executors.newSingleThreadExecutor(newThreadFactory(){
- publicThreadnewThread(Runnablerunnable){
- Threadthread=newThread(runnable,"SmackListenerProcessor("
- +connection.connectionCounterValue+")");
- thread.setDaemon(true);
- returnthread;
- }
- });
- resetParser();
- }
- /**
- *Parsetop-levelpacketsinordertoprocessthemfurther.
- *
- *@paramthreadthethreadthatisbeingusedbythereadertoparse
- *incomingpackets.
- */
- privatevoidparsePackets(Threadthread){
- try{
- inteventType=parser.getEventType();
- do{
- if(eventType==XmlPullParser.START_TAG){
- if(parser.getName().equals("message")){
- processPacket(PacketParserUtils.parseMessage(parser));
- }elseif(parser.getName().equals("iq")){
- processPacket(PacketParserUtils.parseIQ(parser,connection));
- }elseif(parser.getName().equals("presence")){
- processPacket(PacketParserUtils.parsePresence(parser));
- }
构造函数和init()方法PacketWriter一样, 不多说了. 直接看parsePackets(). 在parsePackets()是直接调用processPacket()方法解析, 我们再来看processPacket()方法:
[java] view plain copy
- /**
- *Processesapacketafterit'sbeenfullyparsedbyloopingthroughthe
- *installedpacketcollectorsandlistenersandlettingthemexaminethe
- *packettoseeiftheyareamatchwiththefilter.
- *
- *@parampacketthepackettoprocess.
- */
- privatevoidprocessPacket(Packetpacket){
- if(packet==null){
- return;
- }
- //Loopthroughallcollectorsandnotifytheappropriateones.
- for(PacketCollectorcollector:connection.getPacketCollectors()){
- collector.processPacket(packet);
- }
- //Delivertheincomingpackettolisteners.
- listenerExecutor.submit(newListenerNotification(packet));
- }
[java] view plain copy
- /**
- *Arunnabletonotifyalllistenersofapacket.
- */
- privateclassListenerNotificationimplementsRunnable{
- privatePacketpacket;
- publicListenerNotification(Packetpacket){
- this.packet=packet;
- }
- publicvoidrun(){
- //循环读取注册了的监听器并通知处理packet
- for(ListenerWrapperlistenerWrapper:connection.recvListeners.values()){
- listenerWrapper.notifyListener(packet);
- }
- }
- }
在ListenerNotification的run方法中, 是循环读取connection.recvListeners.values()获取ListenerWrapper .
那么ListenerWrapper 是什么呢? 我们首先来看这里connection.recvListeners.values(), 这connection实际上
是一个XMPPConnection的一个实例, 而XMPPConnection继承了Connection,recvListeners实际上是Connection
的一个成员变量. 然后再来看ListenerWrapper类:
[java] view plain copy
- /**
- *Awrapperclasstoassociateapacketfilterwithalistener.
- *
- */
- protectedstaticclassListenerWrapper{
- privatePacketListenerpacketListener;
- privatePacketFilterpacketFilter;
- /**
- *Createaclasswhichassociatesapacketfilterwithalistener.
- *
- *@parampacketListenerthepacketlistener.
- *@parampacketFiltertheassociatedfilterornullifitlistenfor
- *allpackets.
- */
- publicListenerWrapper(PacketListenerpacketListener,PacketFilterpacketFilter){
- this.packetListener=packetListener;
- this.packetFilter=packetFilter;
- }
- /**
- *Notifyandprocessthepacketlistenerifthefiltermatchesthe
- *packet.
- *@parampacketthepacketwhichwassentorreceived.
- */
- publicvoidnotifyListener(Packetpacket){
- if(packetFilter==null||packetFilter.accept(packet)){
- packetListener.processPacket(packet);
- }
- }
- }
ListenerWrapper类实际上是一个包装类, 该类的作用是将packetListener 和packetFilter关联在一起. 那么
packetListener 和packetFilter分别是什么嗯, 查看smack帮助文档可知:
Smack提供灵活的框架来通过两种构造处理收到的 packet:
- org.jivesoftware.smack.PacketCollector—— 一个让您同步等待新packet的类。
- org.jivesoftware.smack.PacketListener—— 一个异步通知您引入的packet的接口。
packet监听器用于事件样式的编程,而packet收集器有一个可以做轮询和阻塞操作的packet的结果队列。 所以,当您想对一个有可能随时到来的packet采取一些操作时,使用packet监听器;而当您想等待一个特别的packet到来时,使用packet收集器。您可以使用XMPPConnection实例创建packet收集器和监听器。
PacketFilter接口决定哪个特别的将会被传递到PacketCollector或PacketListener。filterpackage包中有许多预定义的过滤器。
packetListener 是一个能够处理随时可能到了的packet监听器,packetFilter能够判断packet是否由该packetListener处理
是的话则调用processPacket()方法处理packet. 至此整个过程处理完成
更多相关文章
- android核心技术与最佳实践笔记(一)
- Android学习之多线程编程(handler篇)
- 【Android】BroadcastReceiver发送intent给service或者activity
- Android(安卓)10.0 Activity启动详解(二)
- Android包管理机制(二)PackageInstaller安装APK
- android相机Camera.Parameters所有的参数值
- Android快速开发框架dyh详解(四)---数据层的使用
- Android第三方文件选择器aFileChooser使用方法详解
- Android中SQLite开发详解(四)SQLiteOpenHelper 类和SQLiteDatabase