A. 怎樣搭建一個android開發框架
相對於傳統計算機程序語言來說,Android開發學習資源上還稍微欠缺一些,對於一些基礎應用講解還稍顯匱乏,本篇所講述的Android培訓內容可以幫助大家更好的理解Android項目快速開發框架。結合之前所用的ormlite和hessian,再加上SAE已經支持java,把服務端切換到JAVA,也就有了本文。使用hessian來做數據傳輸,ormlite來實現客戶端與服務端的數據存儲,極大的減少了CRUD工作。本文為探索貼,未正式用於大型項目,歡迎大家討論使用!正文一、簡介1.1 ormliteOrmlite[Object Relational Mapping Lite (ORM Lite)]對象關系映射精簡版(精簡版的ORM)提供了一些簡單的,輕量級持久化Java對象到SQL資料庫,同時也避免了復雜性和更多的標準的ORM包的開銷的功能。支持資料庫的jdbc調用,當然,最重要的肯定是它支持android原生的資料庫api調用sqlite。——轉載自這里。1.2 hessian使用方法參照本博兩篇文章:[hessdroid]Android下使用Hessian與Java服務端通訊[hessdroid]Android下使用Hessian與Java服務端通訊的傳值測試1.3 Android快速開發框架說明考慮如下幾個特點:a). 客戶端(Android)和服務端均使用Java語言b). 客戶端(Android)和服務端均支持Hessian和ormlite框架c). 完整的支持面向對象開發:存儲和交互傳輸二、准備2.1 開發環境為了便於同時開發Android和Java Web,這里下載的是Eclipse IDE for Java EE Developers版本,然後安裝最新的ADT插件和TOMCAT插件。2.2 服務端應用伺服器使用Tomcat,採用Java(JSP/Servlet)來實現服務端的業務邏輯,資料庫使用Mysql。快速框架搭建推薦大家使用XAMPP(集成Apache、MySQL、PHP等,支持綠色安裝)。2.3 客戶端普通的Android環境2.4 通信與存儲說明服務端與客戶端通過Hessian進行數據交換,通過Ormlite保存資料庫(通過JDBC保存到服務端的MYSQL資料庫,也可以直接保存到客戶端的sqlite資料庫);三、代碼3.1 項目工程截圖(服務端)HOLib共用於客戶端和服務端,保證介面和數據對象一致性。3.2 重點代碼分析3.2.1 服務端web.xml<?xml version="1.0" encoding="ISO-8859-1"?><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name>user</servlet-name> <servlet-class>com.nmbb.ho.server.servlet.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>user</servlet-name> <url-pattern>/user.do</url-pattern> </servlet-mapping> <listener> <listener-class>com.nmbb.ho.server.StartupInit</listener-class> </listener></web-app>StartupInit.javapublic class StartupInit implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent arg0) { try { TableUtils.dropTable(OrmliteHelper.getConnection(), POUser.class, true); //創建資料庫 TableUtils.createTable(OrmliteHelper.getConnection(), POUser.class); } catch (SQLException e) { e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent arg0) { }} 代碼說明:StartupInit可用於創建資料庫表結構,這里用於測試,真實環境注意數據丟失問題。POUser.java@DatabaseTable(tableName = "nmbb_users")public class POUser implements Serializable { /** 用戶編號,6位數字 */ @DatabaseField(generatedId = true) public int suid; /** 用戶名 */ @DatabaseField(width = 30) public String username; /** 密碼 */ @DatabaseField(width = 30) public String password; /** 昵稱 */ @DatabaseField(width = 60) public String nickname; /** 200 正常 201 數據校驗錯誤 202用戶已經存在 */ public int status = 200; /** 用於放錯誤信息 */ public String msg; public POUser() { }} 代碼說明:注意需要一個空的構造函數,其他請參考ormlite資料。UserServlet.java/*** 用戶Servlet** @author 農民伯伯* @see http://www.cnblogs.com/over140/archive/2013/02/19/2917231.html**/public class UserServlet extends HessianServlet implements IUserService { @Override public POUser register(String username, String password) { POUser result = new POUser(); System.out.println("[UserServlet.register]..."); // 檢測數據是否合法 if (isEmpty(username) || isEmpty(password)) { result.status = 201; result.msg = "用戶名或密碼不能為空"; } else { // 檢測用戶是否存在 OrmliteHelper<POUser> db = new OrmliteHelper<POUser>(); if (db.exist(POUser.class, "username", username)) { result.status = 202; result.msg = "用戶名已經存在"; } else { result.username = username; result.password = password; db.create(result);// 入庫 result.msg = "注冊成功"; System.out.println("create user suid:" + result.suid); } } return result; } @Override public List<POUser> query(int suid, int startIndex, int pageSize) { return new OrmliteHelper<POUser>().query(POUser.class, "suid", suid, startIndex, pageSize) ; } /** * 判斷字元串是否為空 * * @param str * @return */ public static boolean isEmpty(String str) { return str == null || str.length() == 0; }}3.2.2 客戶端(Android) public class UserActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void OnClickRegiger(View view) { new AsyncTask<Void, Void, POUser>() { @Override protected POUser doInBackground(Void... params) { String url = "http://192.168.68.23:8081/HOServer/user.do"; HessianProxyFactory factory = new HessianProxyFactory(); try { factory.setDebug(true); factory.setReadTimeout(5000); //不設置會報 expected hessian reply at 0x48 factory.setHessian2Reply(false); IUserService basic = (IUserService) factory.create(IUserService.class, url, getClassLoader()); return basic.register("admin", "123456"); } catch (MalformedURLException e) { Log.e("UserActivity", "OnClickRegiger", e); } catch (Exception e) { Log.e("UserActivity", "OnClickRegiger", e); } return null; } @Override protected void onPostExecute(POUser result) { if (result != null) { if (result.status == 200) { //保存入庫 new DbHelper<POUser>().create(result); } Toast.makeText(UserActivity.this, "" + result.msg, Toast.LENGTH_LONG).show(); } }; }.execute(); }}代碼說明:1、DbHelper在源碼里給出。2、如果項目無法編譯通過,請注意設置項目的字元編碼、JDK版本、Android的版本。三、總結5.1 優點a). 完全面向對象開發b). 降低項目的復雜度,減少引入其他框架所帶來的復雜性c). 非常適合一個開發服務端和客戶端充分的利用的框架的特點,提交開發效率,適合中小型項目快速開發。5.2 缺點a). 注意服務端與客戶端共用id的問題5.3 其他a). ormlite支持標準的JPA助記符,這里。這樣服務端採用Hibernate應該也是可以的,有時間可以做一個整合例子看看。學習語言同做事情一樣,想通其中的關系,就會事半功倍,對語言要深入的理解,
B. 開發Android APP使用的是什麼語言
開發Android APP可以使用Java語言和C語言。
Java是一種編程語言,被特意設計用於互聯網的分布式環境。Java具有類似於C++語言的「形式和感覺」,但它要比C++語言更易於使用,而且在編程時徹底採用了一種「以對象為導向」的方式。
使用Java編寫的應用程序,既可以在一台單獨的電腦上運行,也可以被分布在一個網路的伺服器端和客戶端運行。另外,Java還可以被用來編寫容量很小的應用程序模塊或者applet,做為網頁的一部分使用。applet可使網頁使用者和網頁之間進行互動式操作。
C語言是一門通用計算機編程語言,廣泛應用於底層開發。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。
盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。
Java平台由Java虛擬機(Java Virtual Machine)和Java 應用編程介面(Application Programming Interface、簡稱API)構成。Java 應用編程介面為Java應用提供了一個獨立於操作系統的標准介面,可分為基本部分和擴展部分。
在硬體或操作系統平台上安裝一個Java平台之後,Java應用程序就可運行。現在Java平台已經嵌入了幾乎所有的操作系統。這樣Java程序可以只編譯一次,就可以在各種系統中運行。Java應用編程介面已經從1.1x版發展到1.2版。目前常用的Java平台基於Java1.5,最近版本為Java1.9。
C程序是由一組變數或是函數的外部對象組成的。 函數是一個自我包含的完成一定相關功能的執行代碼段。我們可以把函數看成一個「黑盒子」,你只要將數據送進去就能得到結果,而函數內部究竟是如何工作的,外部程序是不知道的。
C程序中函數的數目實際上是不限的,如果說有什麼限制的話,那就是,一個C程序中必須至少有一個函數,而且其中必須有一個並且僅有一個以main為名,這個函數稱為主函數,整個程序從這個主函數開始執行。
C. 怎麼使用androidpn實現android手機消息推送
由於目前的web項目中要用到android手機消息推送,嘗試過很多中方式之後發現,利用androidpn的部分代碼來實現這個功能是比較方便的。經過使用tsung進行簡單的壓力測試,證明這個框架能夠滿足大多數簡單應用的需求。
Androidpn包含有server和client兩個包,server部分可以作為伺服器單獨運行,也可以嵌入到web項目的servlet中,在tomcat環境中與web項目的其他部分交互。androidpn的簡單用法網上已經有很多文章介紹,這里就不細說了。主要談談如何將androidpn和自己的web程序整合到一起。
Server部分的主要包結構如下:
其中org.androidpn.server.,org.androidpn.server.model和org.androidpn.server.service為使用hibernate鏈接資料庫並實現簡單的用戶登錄認證,開發中可以用我們自己的認證模塊替換。剩下的包就是推送的主體實現。
接下來逐個包來看:
1.util包中的類用來載入resources中的配置文件,在配置文件中可指定監聽埠和ssl證書目錄等屬性。
2.org.androidpn.server.xmpp包裡面定義了一些異常類型,主要是包含有入口類XmppServer,這個類用來啟動和停止server程序。
3.org.androidpn.server.xmpp.auth包裡面是認證的一些類,我們自己的認證模塊可以在這里與androidpn進行結合。
4.org.androidpn.server.xmpp.codec是XMPP協議的XML文件解析包,server收到和發送的消息都要通過這個包來進行xmpp協議編碼和解碼。
5.org.androidpn.server.xmpp.handler包主要是對消息的處理,我們可以針對不同的消息類型定義自己的handler,
6.org.androidpn.server.xmpp.net包負責維護與client之間的持久連接,並實現了一些傳輸方式供發送xmpp消息時使用。
7.org.androidpn.server.xmpp.presence裡面只包含PresenceManager類,用來維護client的在線狀態。
8.org.androidpn.server.xmpp.push包裡面的NotificationManager類包含有向client發送消息的介面。
9.org.androidpn.server.xmpp.router包負責將收到的信息包發送到相應的handler進行處理,是一個路由包。
10.org.androidpn.server.xmpp.session包定義了用來表示持久鏈接的session,每個session包含一條連接的狀態信息。
11.org.androidpn.server.xmpp.ssl是對連接進行ssl認證的工具包。
server發送消息的整個流程主要是:
1. NotificationManager的push介面被調用。
2.使用SessionManager在當前session集合中查找相應的client鏈接。
3.定義自己的XMPP消息格式並組裝。
4.通過相應session,向client發送消息。
在這個流程中我們需要修改的是步驟3,也就是需要定義和組裝自己的xmpp消息,以便於將適當的信息傳到客戶端並便於客戶端解析。一個簡單的消息組裝例子如下:
private IQ createMessageIQ(String title, String message, String userId,
String json) {
Element notification = DocumentHelper.createElement(QName.get(
"message", INQURIE_NAMESPACE));
notification.addElement("title").setText(title);
notification.addElement("text").setText(message);
notification.addElement("userId").setText(userId);
notification.addElement("json").setText(json);
IQ iq = new IQ();
iq.setType(IQ.Type.set);
iq.setChildElement(notification);
return iq;
}
要注意的是在創建element的時候,傳入的namespace要和client解析使用的namespace相匹配。
server端接收和處理消息的流程是:
1.connection收到packet,使用tsc.push.server.xmpp.codec解碼。
2.router根據packet的namespace等信息,將packet路由到相應的handler。
3.handler進行處理。
相應的router和handler類在androidpn中都有例子可以參考,這里就不貼代碼了。開發中只要根據client發送消息的格式,定義自己的router和handler類,然後在PacketRouter中注冊router,在IQRouter中注冊handler即可。
Client部分的主要包結構如下:
這邊包含有消息的收發,解析以及持久連接的發起,重連等功能呢,十分強大,我們開發時完全不用管底層的連接,也不用擔心斷線,可以專注於業務部分的開發。
同時,代碼結構也很簡單。去除android的Service和BroadCast類以及一些工具類和常量類不談:
1.NotificationIQ,NotificationIQProvider,NotificationPacketListener三個類負責對收到的Notification格式的消息進行解析和處理,
2.XmppManager是主控制器,NotificationService通過這個類,在後台維護androidpn連接。
3.PersistentConnectionListener,PhoneStateChangeListener,ReconnectionThread.java三個類則負責監聽手機的狀態並進行斷線重連。
我們自定義消息時需要定義3個類:在***IQ中定義消息的實體,在***IQProvider中將消息轉化為***IQ實體,在***PacketListener中對實體進行處理,具體的實現可參考NotificationIQ,NotificationIQProvider,NotificationPacketListener三個類。在定義這些類之後,還需要在XmppManager中將這3個類中注冊到connection中,代碼如下:
//ConnectTask
connection.connect();
Log.i(LOGTAG, "XMPP connected successfully");
// packet provider
ProviderManager.getInstance().addIQProvider("message",
Constants.NOTIFICATION_NAMESPACE,
new NotificationIQProvider());
//LoginTask
// packet filter
PacketFilter packetFilter = new PacketTypeFilter(
NotificationIQ.class);
// packet listener
PacketListener packetListener = xmppManager
.getNotificationPacketListener();
connection.addPacketListener(packetListener, packetFilter);
需要注意的是,注冊***IQProvider時,傳入的namespace需要和服務端組裝消息時使用的namespace一致,才能正確的收到。
D. 學習android, 需不需要學習struts, hibernate,spring
不需要,如果你只想在Android應用方面發展,學完J2SE基礎 就可以學Android了… 最好是講java GUI部分 (awt,swing)熟悉下先,然後類比學習Android就會很輕鬆了。另外,如果有時間研究下SSH框架對Android框架理解會更有幫助。希望我的回答對你有所幫助!
E. Hibernate+Gson封裝數據時報錯;大神救急,小弟第一次做Android項目,不能退。
我這是用JSON封裝的
個人覺得這個也還蠻方便的,支持LIST MAP對象直轉
Map<String, Object> map=erpCljhManager.findFenYeDataForHql(hql, start, limit);
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
jsonConfig.setExcludes(new String[] { "handler",
"hibernateLazyInitializer" });
jsonConfig.registerJsonValueProcessor(java.util.Date.class,
new JsonDateValueProcessor("yyyy-MM-dd"));
JSONObject jsonObject = JSONObject.fromObject(map, jsonConfig);
out.println(dealString4JSON(jsonObject.toString()));
out.flush();
out.close();
F. Android中可以使用hibernate進行數據存儲操作嗎
不可以 對於android來說它除了使用了一些java的基礎的類庫外,它有自己的API,對於javaee的那些框架對於android不能用的。
Android的五大存儲操作
1. SharedPreferences
2. 文件存儲
3. SQLite存儲
4. ContentProvider
5. 網路存儲
更詳細的在網上搜
G. Android中 Spring、MVC、hibernate這些框架對於安卓開發有什麼用
Spring作用:
Spring提供許多功能,在此我將快速地依次展示其各個主要方面。
首先,讓我們明確Spring范圍。盡管Spring覆蓋了許多方面,但我們已經有清楚的概念,它什麼應該涉及和什麼不應該涉及。
Spring的主要目的是使JavaEE易用和促進好編程習慣。
Spring不重新開發已有的東西。因此,在Spring中你將發現沒有日誌記錄的包,沒有連接池,沒有分布事務調度。這些均有開源項目提供(例如Commons
Logging 用來做所有的日誌輸出,或Commons DBCP用來作數據連接池),或由你的應用程序伺服器提供。因為同樣的的原因,我們沒有提供O/R
mapping層,對此,已有友好的解決辦法如Hibernate和JDO。Spring的目標是使已存在的技術更加易用。
例如,盡管我們沒有底層事務協調處理,但我們提供了一個抽象層覆蓋了JTA或任何其他的事務策略。
Spring沒有直接和其他的開源項目競爭,除非我們感到我們能提供新的一些東西。例如,像許多開發人員,我們從來沒有為Struts高興過,並且感到在MVC
web
framework中還有改進的餘地。在某些領域,例如輕量級的IoC容器和AOP框架,Spring有直接的競爭,但是在這些領域還沒有已經較為流行的解決方案。(Spring在這些區域是開路先鋒。)
Spring也得益於內在的一致性。
所有的開發者都在唱同樣的的贊歌,基礎想法依然是Expert One-on-One J2EE設計與開發的那些。
並且我們已經能夠使用一些主要的概念,例如倒置控制,來處理多個領域。
Spring在應用伺服器之間是可移植的。
當然保證可移植性總是一次挑戰,但是我們避免任何特定平台或非標准化,並且支持在WebLogic,Tomcat,Resin,JBoss,WebSphere和其他的應用伺服器上的用戶。
MVC介紹:
MVC開始是存在於桌面程序中的,M是指業務模型,V是指用戶界面,C則是控制器,使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可以使用不同的表現形式。比如一批統計數據可以分別用柱狀圖、餅圖來表示。C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新。
模型-視圖-控制器(MVC)是Xerox
PARC在二十世紀八十年代為編程語言Smalltalk-80發明的一種軟體設計模式,已被廣泛使用。後來被推薦為Oracle旗下Sun公司Java
EE平台的設計模式,並且受到越來越多的使用ColdFusion和PHP的開發者的歡迎。模型-視圖-控制器模式是一個有用的工具箱,它有很多好處,但也有一些缺點。
hibernate介紹:
Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱資料庫。
Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
H. android上的socket通信的開源框架有哪些
請去360手機助手下載android學習手冊裡面有例子、源碼和文檔
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 組織一個較新的項目,它為開發高性能和高可用性的網路應用程序提供了非常便利的框架。當前發行的 MINA 版本支持基於 Java NIO 技術的 TCP/UDP 應用程序開發、串口通訊程序(只在最新的預覽版中提供),MINA 所支持的功能也在進一步的擴展中。目前正在使用 MINA 的軟體包括有:Apache Directory Project、AsyncWeb、AMQP(Advanced Message Queuing Protocol)、RED5 Server(Macromedia Flash Media RTMP)、ObjectRADIUS、Openfire 等等。
以上是從網上找到的mina框架簡單介紹。
由於正在開發的項目中要求加入及時通信功能(游戲方面),所以在網上找了好幾種框架,像openfire、tigase等都是基於Xmpp協議開發的優秀框架。但這些側重於消息的推送,不適合游戲上的簡單交互。所以後來找到了mina這個框架,順手搭建起來。接下來就是這幾天學習的總結了,文章裡面沒有涉及到邏輯層的方面,只是簡單的實現即時通信功能。資源下載我會放在文章的最後面。
一、相關資源下載
(1)Apache官方網站:http://mina.apache.org/downloads.html
(2) Android用jar包(包括官網的資源,我會一律放在網路網盤下)
二、Mina簡單配置
伺服器端一共要用到四個jar包,包括一個日誌包。將他們放在lib中,並載入進去
分別為mina-core-2.0.7.jar slf4j-log4j12-1.7.6.jar slf4j-api-1.7.6.jar log4j-1.2.14.jar(日誌管理包)
如果要使用日誌的jar包,則要在項目的src目錄下新建一個log4j.properties,添加內容如下:
log4j.rootCategory=INFO, stdout , R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
log4j.logger.com.neusoft=DEBUG
log4j.logger.com.opensymphony.oscache=ERROR
log4j.logger.net.sf.navigator=ERROR
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.apache.struts=WARN
log4j.logger.org.displaytag=ERROR
log4j.logger.org.springframework=DEBUG
log4j.logger.com.ibatis.db=WARN
log4j.logger.org.apache.velocity=FATAL
log4j.logger.com.canoo.webtest=WARN
log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
log4j.logger.org.hibernate=DEBUG
log4j.logger.org.logicalcobwebs=WARN
log4j.rootCategory=INFO, stdout , R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D:\Tomcat 5.5\logs\qc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
log4j.logger.com.neusoft=DEBUG
log4j.logger.com.opensymphony.oscache=ERROR
log4j.logger.net.sf.navigator=ERROR
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.apache.struts=WARN
log4j.logger.org.displaytag=ERROR
log4j.logger.org.springframework=DEBUG
log4j.logger.com.ibatis.db=WARN
log4j.logger.org.apache.velocity=FATAL
log4j.logger.com.canoo.webtest=WARN
log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
log4j.logger.org.hibernate=DEBUG
log4j.logger.org.logicalcobwebs=WARN
Android客戶端要加入的jar包:mina-core-2.0.7.jar slf4j-android-1.6.1-RC1.jar兩個jar包(可能直接使用上面的jar包也會行,我沒試過~)
二、Mina服務端
我這邊使用的是mina2.0版本,所以可能與mina1.0的版本有所不同。那麼首先在伺服器端創建開始
新建一個Demo1Server.class文件,裡麵包含著程序的入口,埠號,Acceptor連接.
1 public class Demo1Server {
2 //日誌類的實現
3 private static Logger logger = Logger.getLogger(Demo1Server.class);
4 //埠號,要求客戶端與伺服器端一致
5 private static int PORT = 4444;
6
7 public static void main(String[] args){
8 IoAcceptor acceptor = null;
9 try{
10 //創建一個非阻塞的server端的Socket
11 acceptor = new NioSocketAcceptor();
12 //設置過濾器(使用mina提供的文本換行符編解碼器)
13 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));
14 //自定義的編解碼器
15 //acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
16 //設置讀取數據的換從區大小
17 acceptor.getSessionConfig().setReadBufferSize(2048);
18 //讀寫通道10秒內無操作進入空閑狀態
19 acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
20 //為接收器設置管理服務
21 acceptor.setHandler(new Demo1ServerHandler());
22 //綁定埠
23 acceptor.bind(new InetSocketAddress(PORT));
24
25 logger.info("伺服器啟動成功... 埠號未:"+PORT);
26
27 }catch(Exception e){
28 logger.error("伺服器啟動異常...",e);
29 e.printStackTrace();
30 }
31 }
32
33 }
一個很簡單的程序入口吧,簡單的說就是在伺服器上設置一個消息接收器,讓它監聽從埠傳過來的消息並進行處理。那麼接下來我們看看怎麼進行消息處理。
新建一個消息處理類,或者說是是業務邏輯處理器——Demo1ServerHandler,它繼承了IoHandlerAdapter類,它默認覆蓋了七個方法,而我們主要使用messageReceived()。
public class Demo1ServerHandler extends IoHandlerAdapter {
public static Logger logger = Logger.getLogger(Demo1ServerHandler.class);
//從埠接受消息,會響應此方法來對消息進行處理
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String msg = message.toString();
if("exit".equals(msg)){
//如果客戶端發來exit,則關閉該連接
session.close(true);
}
//向客戶端發送消息
Date date = new Date();
session.write(date);
logger.info("伺服器接受消息成功...");
super.messageReceived(session, message);
}
//向客服端發送消息後會調用此方法
@Override
public void messageSent(IoSession session, Object message) throws Exception {
logger.info("伺服器發送消息成功...");
super.messageSent(session, message);
}
//關閉與客戶端的連接時會調用此方法
@Override
public void sessionClosed(IoSession session) throws Exception {
logger.info("伺服器與客戶端斷開連接...");
super.sessionClosed(session);
}
//伺服器與客戶端創建連接
@Override
public void sessionCreated(IoSession session) throws Exception {
logger.info("伺服器與客戶端創建連接...");
super.sessionCreated(session);
}
//伺服器與客戶端連接打開
@Override
public void sessionOpened(IoSession session) throws Exception {
logger.info("伺服器與客戶端連接打開...");
super.sessionOpened(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
logger.info("伺服器進入空閑狀態...");
super.sessionIdle(session, status);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
logger.info("伺服器發送異常...");
super.exceptionCaught(session, cause);
}
}
很直白的一段程序,相當於將伺服器分成了七個狀態,而每個狀態都有自己的一套邏輯處理方案。
至此,一個最簡單的Mina伺服器框架就搭好了,我們可以使用電腦上的telnet命令來測試一下伺服器能否使用
cmd控制台—>telnet <ip地址> <埠號> 如我的伺服器ip地為192.168.1.10 那我就寫telnet 192.168.1.10 4444 .此時我們可以看到輸出日誌為
此時連接已經創建,我們在輸入信息伺服器就會對信息進行處理,並給出相應的應答。
(telnet的用法不知道的可以自行網路)
三、Mina客戶端(Android端)
伺服器簡單搭建完畢,那麼開始在Android端是配置伺服器吧。同樣的不要忘記載入jar包, 由於Android自帶了Logout,所以就不使用Mina的日誌包了。
由於接受消息會阻塞Android的進程,所以我把它開在子線程中(同時將其放在Service中,讓其在後台運行)
1 public class MinaThread extends Thread {
2
3 private IoSession session = null;
4
5 @Override
6 public void run() {
7 // TODO Auto-generated method stub
8 Log.d("TEST","客戶端鏈接開始...");
9 IoConnector connector = new NioSocketConnector();
10 //設置鏈接超時時間
11 connector.setConnectTimeoutMillis(30000);
12 //添加過濾器
13 //connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));
14 connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),LineDelimiter.WINDOWS.getValue(),LineDelimiter.WINDOWS.getValue())));
15 connector.setHandler(new MinaClientHandler(minaService));
16
17 try{
18 ConnectFuture future = connector.connect(new InetSocketAddress(ConstantUtil.WEB_MATCH_PATH,ConstantUtil.WEB_MATCH_PORT));//創建鏈接
19 future.awaitUninterruptibly();// 等待連接創建完成
20 session = future.getSession();//獲得session
21 session.write("start");
22 }catch (Exception e){
23 Log.d("TEST","客戶端鏈接異常...");
24 }
25 session.getCloseFuture().awaitUninterruptibly();//等待連接斷開
26 Log.d("TEST","客戶端斷開...");
27 connector.dispose();
28 super.run();
29 }
30
31 }
不知道你們注意到了沒,客戶端的代碼與伺服器端的極其相似,不同的是伺服器是創建NioSocketAcceptor對象,而客戶端是創建NioSocketConnect對象。當然同樣需要添加編碼解碼過濾器和業務邏輯過濾器。
業務邏輯過濾器代碼:
1 public class MinaClientHandler extends IoHandlerAdapter{
2
3
4 @Override
5 public void exceptionCaught(IoSession session, Throwable cause)
6 throws Exception {
7 Log.d("TEST","客戶端發生異常");
8 super.exceptionCaught(session, cause);
9 }
10
11 @Override
12 public void messageReceived(IoSession session, Object message)
13 throws Exception {
14 String msg = message.toString();
15 Log.d("TEST","客戶端接收到的信息為:" + msg);
16 super.messageReceived(session, message);
17 }
18
19 @Override
20 public void messageSent(IoSession session, Object message) throws Exception {
21 // TODO Auto-generated method stub
22 super.messageSent(session, message);
23 }
24 }
方法功能與伺服器端一樣。測試這里就不做了。可以的話自己寫個Demo效果更好
四、Mina的更多功能
拿到所有客戶端Session
Collection<IoSession> sessions = session.getService().getManagedSessions().values();
自定義編碼解碼器,可以對消息進行預處理。要繼承ProtocolEncoder和ProtocolDecode類。
數據對象的傳遞
這些功能不便放在這里講了,可能我會以後再找機會另開一篇來講述這些功能~,大家可以瀏覽結尾處的參考文章來加深對mina的理解。
在我認為,熟悉和快速使用一個新的的框架可以看出一個程序員的水平,同樣及時總結和歸納自己學到的新知識也是一個好的程序員該具有的習慣。那麼Mina的簡單搭建就到這里為止了,希望對大家有所幫助