android下服務器推送實現 androidpn分析
>服務器推送技術,目前應用廣泛的大部分都是對xmpp協議的在此封裝。
>沒接觸過xmpp?在linux用一些im客戶端,默認都會讓你添加支持xmpp協議的賬戶,比如icq、msn等等,另外,不都說qq也是基于xmpp的么,包括android下gmail、gtalk等等也都是基于xmpp協議的。
>下面對android下服務器推送技術的一個封裝androidpn進行簡單的分析,以后還會對xmpp協議的android封裝smack進行分析學習。
>androidpn也是構建與xmpp協議之上,好在它把服務端與客戶端都進行了封裝,很容易使用與擴展,提高了很多開發人員的效率,這也是選擇它最好的理由。
客戶端簡易流程
---
step1:配置客戶端
位于工程`->res->raw->androidpn.properties`文件
apiKey=1234567890 #key
xmppHost=192.168.1.1 #ip
xmppPort=5222 #端口
step2:
//創建新的服務
ServiceManager serviceManager = new ServiceManager(this);
//設置通知欄圖標
serviceManager.setNotificationIcon(R.drawable.notification);
//啟動服務
serviceManager.startService();
詳細分析
---
初始化ServiceManager:
this.context = context;
//這里獲取調用者activity得包名類名
if (context instanceof Activity) {
Log.i(LOGTAG, "Callback Activity...");
Activity callbackActivity = (Activity) context;
callbackActivityPackageName = callbackActivity.getPackageName();
callbackActivityClassName = callbackActivity.getClass().getName();
}
//loadProperties()讀取raw中androidpn.properties文件的內容,并返回Properties對象
props = loadProperties();
apiKey = props.getProperty("apiKey", "");
xmppHost = props.getProperty("xmppHost", "127.0.0.1");
xmppPort = props.getProperty("xmppPort", "5222");
//將上面獲取的Properties存入SharedPreferences方便以后直接調用
sharedPrefs = context.getSharedPreferences(
Constants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
Editor editor = sharedPrefs.edit();
...
...
...
editor.commit();
啟動服務startService()
//用一個線程開啟服務
Thread serviceThread = new Thread(new Runnable() {
@Override
public void run() {
Intent intent = NotificationService.getIntent();
context.startService(intent);
}
});
serviceThread.start();
NotificationService類分析,它是Service的子類,著重分析一下這個Service
public NotificationService() {
/*NotificationReceiver為BroadcastReceiver的子類
*用于接收推送廣播并用NotificationManager通知用戶
*也就是系統通知欄的通知
*/
notificationReceiver = new NotificationRece
/*ConnectivityReceiver接收手機網絡狀態的廣播
*來管理xmppManager與服務器的連接與斷開
*/
connectivityReceiver = new ConnectivityReceiver(this);
/*集成于android.telephony.PhoneStateListener,
*同上,用于監聽數據鏈接的狀態
*/
phoneStateListener = new PhoneStateChangeListener(this);
//線程池
executorService = Executors.newSingleThreadExecutor();
/*TaskSubmitter類包含了向上面的線程池提交一個Task任務
*的方法
*/
taskSubmitter = new TaskSubmitter(this);
/*任務計數器
*用以維護當前工作的Task
*/
taskTracker = new TaskTracker(this);
}
一切聲明好以后,就開始執行服務了
private void start() {
Log.d(LOGTAG, "start()...");
//注冊通知廣播接收者
registerNotificationReceiver();
//注冊手機網絡連接狀態接收者
registerConnectivityReceiver();
// Intent intent = getIntent();
// startService(intent);
//開始與服務器進行xmpp長鏈接
//關于XmppManager后面會有分析
xmppManager.connect();
}
XmppManager 管理Xmpp鏈接:
public XmppManager(NotificationService notificationService) {
context = notificationService;
//獲取Task提交管理器,這里用于維護并行任務
taskSubmitter = notificationService.getTaskSubmitter();
//Task的計數器
taskTracker = notificationService.getTaskTracker();
//下面都是獲取配置信息
sharedPrefs = notificationService.getSharedPreferences();
xmppHost = sharedPrefs.getString(Constants.XMPP_HOST, "localhost");
xmppPort = sharedPrefs.getInt(Constants.XMPP_PORT, 5222);
username = sharedPrefs.getString(Constants.XMPP_USERNAME, "");
password = sharedPrefs.getString(Constants.XMPP_PASSWORD, "");
/*設置xmpp鏈接狀態的監聽器,查看代碼發現Xmpp鏈接狀態有5種
* 1 connectionClosed
* 2 connectionClosedOnError
* 3 reconnectingIn
* 4 reconnectionFailed
* 5 reconnectionSuccessful
*/
connectionListener = new PersistentConnectionListener(this);
/* 服務器推送監聽器
* 服務器如果有消息推送,NotificationPacketListener會
* 自己解析好,并通過XmppManager發送廣播
*/
notificationPacketListener = new NotificationPacketListener(this);
//當xmpp因異常重新連接服務器時,這期間發生異常的話,會在這個handler中處理
handler = new Handler();
//任務隊列
taskList = new ArrayList();
/* 當xmppManager因異常與服務器斷開鏈接時
* ReconnectionThread會在一定的時間內嘗試重新連接
* 也就是說,當PersistentConnectionListener監聽器監聽到異常斷開連接
* 會調用ReconnectionThread中重新連接的方法以進行連接嘗試
reconnection = new ReconnectionThread(this);
}
androidpn與服務器連接流程
---
這里涉及很多smack包的操作,下篇會分析android下xmpp協議的封裝smack。
_Runable 1: ConnectTask_
與服務器建立鏈接
_Runable 1.5: RegisterTask_
如果沒有配置androidpn客戶端的賬戶信息,它會自動生成一個隨機賬戶并注冊到服務器
_Runalbe 2: LoginTask_
讀取本地的賬戶信息,并登錄,開始等待服務器推送消息
浙公網安備 33010602011771號