Android之基於XMPP協議即時通信軟件(二)

2013博客之星投票請移步:http://vote.blog.csdn.net/blogstaritem/blogstar2013/weidi1989java

昨天給你們粗略的介紹了一下我那個簡單的項目:Android之基於XMPP協議即時通信軟件(一)數據庫

從今天開始,就詳細展開的介紹設計思路,一是給本身作個總結,二是但願能給各位朋友一點點幫助吧!設計模式

也許和不少剛剛開始入行程序猿的朋友同樣,我最初也是每開始一個新項目,只是稍微思考一下便開始寫代碼。一個星期後,儘管實現了部分功能,卻發現本身有點亂了,由於又忽然生出不少新的想法,因而又順着思路寫下去,再持續一段時間,就會發現這個項目作不下去了。代碼重複不少,並且bug也是層出不窮。所以不得不推翻從新開始,浪費了不少時間。因此說,開始前的準備工做是至關重要的。服務器

通常說來完成一個項目能夠分紅三步:框架

首先:畫幾天時間好好理清思路,能夠在草稿紙上寫寫畫畫,列出必須實現的功能已經界面特效等等,作到成竹在胸。ide

其次:開始搭建框架,定義好全部功能的接口,而且註釋好作什麼用,這是方便團隊合做的項目,我的項目也能夠養成寫註釋的好習慣。函數

最後:分開實現各部分功能,而且分開調試,能夠單獨獨立成一個應用或者單元測試模塊。好比說本應用的全部界面效果都是獨立成一個應用測試無誤後才最後合入的。工具

我這個項目呢,一開始是完成了全部的界面模塊工做,由於是直接從以前的項目移植過來的,稍微修改了一下,因此這部分省掉了不少時間。單元測試

重心就直接放在了功能實現這方面了。功能模塊部分就是下面兩個包:com.way.service和 com.way.smack測試

首先是定義通用接口,主要就是將第三方包asmack.jar中須要用到的東西拿出來,這個包是很是龐大的,可是咱們這個小應用並非須要實現全部的功能,因此,抽取本身須要的那部分就能夠了,定義成接口,方便之後擴展須要的功能,代碼以下:

[java] view plaincopyprint?/**

  • 首先定義一些接口,須要實現一些什麼樣的功能,
  • @author way

/
public interface Smack {
/
* * 登錄 *
* @param account * 帳號 * @param password * 密碼 * @return 是否登錄成功 * @throws XXException * 拋出自定義異常,以便統一處理登錄失敗的問題 */
public boolean login(String account, String password) throws XXException;

/** 
 * 註銷登錄 
 *  
 * @return 是否成功 
 */  
public boolean logout();  

/** 
 * 是否已經鏈接上服務器 
 *  
 * @return 
 */  
public boolean isAuthenticated();  

/** 
 * 添加好友 
 *  
 * @param user 
 *            好友id 
 * @param alias 
 *            暱稱 
 * @param group 
 *            所在的分組 
 * @throws XXException 
 */  
public void addRosterItem(String user, String alias, String group)  
        throws XXException;  

/** 
 * 刪除好友 
 *  
 * @param user 
 *            好友id 
 * @throws XXException 
 */  
public void removeRosterItem(String user) throws XXException;  

/** 
 * 修改好友暱稱 
 *  
 * @param user 
 *            好友id 
 * @param newName 
 *            新暱稱 
 * @throws XXException 
 */  
public void renameRosterItem(String user, String newName)  
        throws XXException;  

/** 
 * 移動好友到新分組 
 *  
 * @param user 
 *            好友id 
 * @param group 
 *            新組名 
 * @throws XXException 
 */  
public void moveRosterItemToGroup(String user, String group)  
        throws XXException;  

/** 
 * 重命名分組 
 *  
 * @param group 
 *            以前的組名 
 * @param newGroup 
 *            新組名 
 */  
public void renameRosterGroup(String group, String newGroup);  

/** 
 * 請求好友從新受權,用在添加好友失敗時,重複添加 再次向對方發出申請 
 *  
 * @param user 
 *            好友id 
 */  
public void requestAuthorizationForRosterItem(String user);  

/** 
 * 添加新分組 
 *  
 * @param group 
 */  
public void addRosterGroup(String group);  

/** 
 * 設置當前在線狀態 
 */  
public void setStatusFromConfig();  

/** 
 * 發送消息 
 *  
 * @param user 
 * @param message 
 */  
public void sendMessage(String user, String message);  

/** 
 * 向服務器發送心跳包,保持長鏈接 經過一個鬧鐘控制,定時發送, 
 */  
public void sendServerPing();  

/** 
 * 從jid中獲取好友名 
 *  
 * @param jid 
 * @return 
 */  
public String getNameForJID(String jid);

}

/**

  • 首先定義一些接口,須要實現一些什麼樣的功能,
  • @author way

/ public interface Smack { /* * 登錄 * * @param account * 帳號 * @param password * 密碼 * @return 是否登錄成功 * @throws XXException * 拋出自定義異常,以便統一處理登錄失敗的問題 */ public boolean login(String account, String password) throws XXException;

/**
 * 註銷登錄
 * 
 * @return 是否成功
 */
public boolean logout();

/**
 * 是否已經鏈接上服務器
 * 
 * @return
 */
public boolean isAuthenticated();

/**
 * 添加好友
 * 
 * @param user
 *            好友id
 * @param alias
 *            暱稱
 * @param group
 *            所在的分組
 * @throws XXException
 */
public void addRosterItem(String user, String alias, String group)
		throws XXException;

/**
 * 刪除好友
 * 
 * @param user
 *            好友id
 * @throws XXException
 */
public void removeRosterItem(String user) throws XXException;

/**
 * 修改好友暱稱
 * 
 * @param user
 *            好友id
 * @param newName
 *            新暱稱
 * @throws XXException
 */
public void renameRosterItem(String user, String newName)
		throws XXException;

/**
 * 移動好友到新分組
 * 
 * @param user
 *            好友id
 * @param group
 *            新組名
 * @throws XXException
 */
public void moveRosterItemToGroup(String user, String group)
		throws XXException;

/**
 * 重命名分組
 * 
 * @param group
 *            以前的組名
 * @param newGroup
 *            新組名
 */
public void renameRosterGroup(String group, String newGroup);

/**
 * 請求好友從新受權,用在添加好友失敗時,重複添加 再次向對方發出申請
 * 
 * @param user
 *            好友id
 */
public void requestAuthorizationForRosterItem(String user);

/**
 * 添加新分組
 * 
 * @param group
 */
public void addRosterGroup(String group);

/**
 * 設置當前在線狀態
 */
public void setStatusFromConfig();

/**
 * 發送消息
 * 
 * @param user
 * @param message
 */
public void sendMessage(String user, String message);

/**
 * 向服務器發送心跳包,保持長鏈接 經過一個鬧鐘控制,定時發送,
 */
public void sendServerPing();

/**
 * 從jid中獲取好友名
 * 
 * @param jid
 * @return
 */
public String getNameForJID(String jid);

}

真正的實現就留給他的子工具類SmackImpl。昨天我說過,本應用只有一個服務:XXService,他時繼承自BaseService,BaseService也是完成了一部分通用的功能,好比說通知欄消息處理等。在XXService中,咱們主要是處理Activity與Smack中鏈接工做。每一個Activity在onResume時,就與該XXService綁定,綁定以後,即可調用該Service中的全部公共函數,好比說登錄、發消息等等,而後Service再調用Smack中已經定義好的各類接口函數,便可完成與服務器的交互。沒錯,其實這就是MVC設計模式。

Service擔當這個C的角色,Activity就是V的角色,Smack就是M了。

如今咱們的Activity能夠調用Service中的函數提交消息給服務器了,這是單方面的,咱們同時須要得到服務器返回的信息,好比說是否登錄成功、收消息之類。這個任務就天然的落到了回調接口IConnectionStatusCallback身上了,在綁定服務成功的同時,咱們註冊此回調接口,下面是此接口定義的惟一一個函數。也許眼尖的朋友會問了,爲何沒有收到新消息的回調,其實一開始我是加了的,後面由於將數據庫改爲了ContentProvider,就能夠去掉了,由於收消息能夠經過監聽數據庫動態變化嘛,對吧?這就是ContentProvider的好處所在,這個留待後續詳細說,這裏只是說起一下。

[java] view plaincopyprint?/**

  • 服務器回調接口
  • @author way

/
public interface IConnectionStatusCallback {
/
* * 鏈接狀態改變 *
* @param connectedState * 鏈接狀態,有鏈接、未鏈接、連接中三種 * @param reason * 鏈接失敗的緣由 */
public void connectionStatusChanged(int connectedState, String reason);
}

/**

  • 服務器回調接口
  • @author way

/ public interface IConnectionStatusCallback { /* * 鏈接狀態改變 * * @param connectedState * 鏈接狀態,有鏈接、未鏈接、連接中三種 * @param reason * 鏈接失敗的緣由 */ public void connectionStatusChanged(int connectedState, String reason); } 在綁定服務成功的時候,將此回調傳遞給Service,好比登錄界面的ServiceConnection:

[java] view plaincopyprint?ServiceConnection mServiceConnection = new ServiceConnection() {

@Override  
public void onServiceConnected(ComponentName name, IBinder service) {  
    mXxService = ((XXService.XXBinder) service).getService();  
    //註冊回調   
    mXxService.registerConnectionStatusCallback(LoginActivity.this);  
}  

@Override  
public void onServiceDisconnected(ComponentName name) {  
    mXxService.unRegisterConnectionStatusCallback();  
    mXxService = null;  
}

};

ServiceConnection mServiceConnection = new ServiceConnection() {

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		mXxService = ((XXService.XXBinder) service).getService();
		//註冊回調
		mXxService.registerConnectionStatusCallback(LoginActivity.this);
	}

	@Override
	public void onServiceDisconnected(ComponentName name) {
		mXxService.unRegisterConnectionStatusCallback();
		mXxService = null;
	}

};

就這樣,總體與服務器交互的基本框架就完成了。很簡單對吧?

OK,今天就到這裏了,以上僅是本人的一點心得體會,後續將詳細講解功能接口Smack的實現以及如何處理聯繫人和聊天記錄數據庫等功能,很是感謝你看到了文章末尾,話說,你是否忘記投票了呢?O(∩_∩)O哈哈~

相關文章
相關標籤/搜索