編輯:關於Android編程
昨天給大家粗略的介紹了一下我那個簡單的項目:Android之基於XMPP協議即時通訊軟件(一)
從今天開始,就詳細展開的介紹設計思路,一是給自己做個總結,二是希望能給各位朋友一點點幫助吧!
也許和很多剛剛開始入行程序猿的朋友一樣,我最初也是每開始一個新項目,只是稍微思考一下便開始寫代碼。一個星期後,盡管實現了部分功能,卻發現自己有點亂了,因為又突然生出很多新的想法,於是又順著思路寫下去,再持續一段時間,就會發現這個項目做不下去了。代碼重復很多,而且bug也是層出不窮。因此不得不推翻重新開始,浪費了很多時間。所以說,開始前的准備工作是相當重要的。
一般說來完成一個項目可以分成三步:
首先:畫幾天時間好好理清思路,可以在草稿紙上寫寫畫畫,列出必須實現的功能已經界面特效等等,做到胸有成竹。
其次:開始搭建框架,定義好所有功能的接口,並且注釋好做什麼用,這是方便團隊合作的項目,個人項目也可以養成寫注釋的好習慣。
最後:分開實現各部分功能,並且分開調試,可以單獨獨立成一個應用或者單元測試模塊。比如說本應用的所有界面效果都是獨立成一個應用測試無誤後才最後合入的。
我這個項目呢,一開始是完成了所有的界面模塊工作,因為是直接從之前的項目移植過來的,稍微修改了一下,所以這部分省掉了很多時間。
重心就直接放在了功能實現這方面了。功能模塊部分就是下面兩個包:com.way.service和 com.way.smack
首先是定義通用接口,主要就是將第三方包asmack.jar中需要用到的東西拿出來,這個包是非常龐大的,但是我們這個小應用並不是需要實現所有的功能,所以,抽取自己需要的那部分就可以了,定義成接口,方便以後擴展需要的功能,代碼如下:
/** * 首先定義一些接口,需要實現一些什麼樣的功能, * * @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); }
Service擔當這個C的角色,Activity就是V的角色,Smack就是M了。
現在我們的Activity可以調用Service中的函數提交消息給服務器了,這是單方面的,我們同時需要獲得服務器返回的信息,比如說是否登陸成功、收消息之類。這個任務就自然的落到了回調接口IConnectionStatusCallback身上了,在綁定服務成功的同時,我們注冊此回調接口,下面是此接口定義的唯一一個函數。也許眼尖的朋友會問了,為什麼沒有收到新消息的回調,其實一開始我是加了的,後面因為將數據庫改成了ContentProvider,就可以去掉了,因為收消息可以通過監聽數據庫動態變化嘛,對吧?這就是ContentProvider的好處所在,這個留待後續詳細說,這裡只是提及一下。
/** * 服務器回調接口 * * @author way * */ public interface IConnectionStatusCallback { /** * 連接狀態改變 * * @param connectedState * 連接狀態,有連接、未連接、鏈接中三種 * @param reason * 連接失敗的原因 */ public void connectionStatusChanged(int connectedState, String reason); }
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; } };
我們一般直接從攝像頭和麥克風取數據,經過編碼,保存為文件。android的視頻錄制需要使用到MediaRecorder,MediaRecorder除了可以用於錄制音頻,還
Activity的啟動模式實際上是定義了Activity實例與當前Task的關聯方式。所以想要清楚的了解Activity的啟動模式,首先得清楚Task是怎麼回事。Task
Android開發中,我們常使用到ListView視圖,下面介紹ListView的幾種使用方法。 主界面首先,在主界面上添加幾個按鈕,用於界面跳轉。界面布局:&
Servlet在不實現SingleThreadModel的情況下運行時是以單個實例模式,如下圖,這種情況下,Wrapper容器只會通過反射實例化一個Servlet對象,對