溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

AndroidPN的學(xué)習(xí)研究(三)源碼流程分析

發(fā)布時間:2020-07-21 12:51:44 來源:網(wǎng)絡(luò) 閱讀:227 作者:ptghb 欄目:移動開發(fā)

在客戶端中,我們在AndroidManifest.xml文件中找到程序入口,即如下的DemoAppActivity類,

在此類中主要代碼如下

 ServiceManager serviceManager = new ServiceManager(this);

 serviceManager.setNotificationIcon(R.drawable.notification);

 serviceManager.startService();

一路跟進(jìn),NotificationService中有個XmppManager類的調(diào)用(xmppManager.connect();),而XmppManager類就是客戶端比較重要的類,有這幾個方法

public void connect() {

    Log.d(LOGTAG, "connect()...");

    submitLoginTask();

  }


private void submitConnectTask() {

    Log.d(LOGTAG, "submitConnectTask()...");

    addTask(new ConnectTask());

  }


  private void submitRegisterTask() {

    Log.d(LOGTAG, "submitRegisterTask()...");

    submitConnectTask();

    addTask(new RegisterTask());

  }


  private void submitLoginTask() {

    Log.d(LOGTAG, "submitLoginTask()...");

    submitRegisterTask();

    addTask(new LoginTask());

  }


addTask方法中有一個線程隊列,依次添加連接,注冊和登陸任務(wù)。用runTask方法執(zhí)行這些任務(wù)

在XmppManager類中有三個內(nèi)部類,即連接(ConnectTask),注冊(RegisterTask),登陸(LoginTask)三個線程類。

連接類負(fù)責(zé)與服務(wù)端的連接。


注冊類中,即用UUID生成唯一的username和password,然后把它們保存到SharedPreferences中

final String newUsername = newRandomUUID();

final String newPassword = newRandomUUID();

.....

 Editor editor = sharedPrefs.edit();

 editor.putString(Constants.XMPP_USERNAME, newUsername);

 editor.putString(Constants.XMPP_PASSWORD, newPassword);

 editor.commit();

而在登陸類中,首先進(jìn)行連接登陸,把客戶端的信息更新到服務(wù)端,即

xmppManager.getConnection().login(

         xmppManager.getUsername(),

         xmppManager.getPassword(), XMPP_RESOURCE_NAME);

這個操作可能執(zhí)行多次,直到真正更新到服務(wù)器。

執(zhí)行連接登陸時,服務(wù)端就會收到信息。

在服務(wù)端,接受消息的類是router包(org.androidpn.server.xmpp.router)下的PacketRouter類,在這里分析消息的類型是什么類型,然后在調(diào)用具體的Router,如響應(yīng)登陸的IQRouter。

如果是登陸(即通過唯一的客戶端標(biāo)識獲取的session就是為null的),那么就要對這個包進(jìn)行處理。處理消息包的操作是在 org.androidpn.server.xmpp.handler包下進(jìn)行的。把消息包處理完后就在維護(hù)連接的 org.androidpn.server.xmpp.net包下的Connection類中傳遞消息包到客戶端

XMLWriter xmlSerializer = new XMLWriter(new IoBufferWriter(

      buffer, (CharsetEncoder) encoder.get()),

      new OutputFormat());

xmlSerializer.write(packet.getElement());

xmlSerializer.flush();

buffer.flip();

ioSession.write(buffer);


如果登陸失敗,就獲取這個異常,重新進(jìn)行登陸連接直到登陸成功。


注冊登錄的流程就如下所述,下面再講一下,在服務(wù)端怎么發(fā)送消息到客戶端,客戶端怎么發(fā)消息到服務(wù)端,客戶端怎么接收來自服務(wù)端的消息(服務(wù)端接收來自客戶端的消息在如下登陸時已經(jīng)講了)


在服務(wù)端的推送消息的頁面中(form.jsp),是通過notification.do?action=send來跳轉(zhuǎn)后臺的,那么這個后臺是哪個類 呢,在web.xml中,我們可以看到,攔截器都是spring的類,即這些都通過spring來托管了,那么我們再打開dispatcher- servlet.xml的spring的配置文件,可以看到

class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

/index.do=filenameController

/user.do=userController

/session.do=sessionController

/notification.do=notificationController


notification.do跳轉(zhuǎn)的頁面就是notificationController即org.androidpn.server.console.controller.NotificationController這個類

class="org.androidpn.server.console.controller.NotificationController">


打開NotificationController類發(fā)現(xiàn)它是調(diào)用了NotificationManager

 if (broadcast.equalsIgnoreCase("Y")) {

      notificationManager.sendBroadcast(apiKey, title, message, uri);

    } else {

      notificationManager.sendNotifcationToUser(apiKey, username, title,

          message, uri);

  }


一路跟進(jìn),可以發(fā)現(xiàn)最終發(fā)送消息的類還是Connection的deliver方法。而中間的過程就是解析和生成消息的操作


那么客戶端怎么接受消息呢,這個類應(yīng)該是一個監(jiān)聽器,從類名和在客戶端一路跟進(jìn)的過程中,我們大概可以知道是NotificationPacketListener類,在這個類中獲取各個節(jié)點的值,然后在客戶端上發(fā)送一個通知


那么客戶端發(fā)送消息的類又是在哪個類中呢,我們可以參考服務(wù)端的發(fā)送消息的類是在哪里,沒錯,是在Connection類中,那么我們在客戶端的連接類中 尋找一下是否有發(fā)送消息的類。果然,在org.jivesoftware.smack包下的XMPPConection這個類中有個發(fā)送消息的方法 sendPacket。我們可以通過xmppManager.getConnection()來獲取連接。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI