編輯:關於Android編程
最近,同學的同學找我做了一款簡單的安卓手機軟件,第一次,一個人,做一個完整的項目。所以,在這裡總結一下完整的開發流程和步驟,方便後來人入門學習。
其實,我是一個新手,沒有系統的學過android也沒有系統的學過WCF,這些都是自己一點一點嘗試出來的。
先說一下我的基礎:
安卓在三年前接觸過,當時亂看一氣。主要看的網站就是這個(http://www.fenby.com);今年三月份,深入學習了數據庫相關知識,對於數據的增刪改查,三范式,E-R有了深刻了解;今天五月份,負責一個軟件開發的服務器端的接口編寫,也就是用WCF技術實現接口。如今,自己做了一個項目。下面開始正式的項目介紹。
本系統設計三部分內容:
數據庫的設計;服務器端接口開發;Android客戶端功能實現和接口調用。
說實話,數據庫的設計完全就是另外一門技術,能夠“設計表的結構,靈活使用增刪改查等語句”,就夠了。
設計的時候,要符合三范式,注意表和屬性的命名規范即可。
在這裡推薦大家使用一個PowerDesigner軟件,這個軟件上手快,可視化的方式設計E-R圖,自動生成各種數據庫系統sql腳本,還能快速生成用戶字典等文本文件。在這裡就不多說了,讀者可以自己了解。這個軟件只是提高效率僅此而已。
前期使用阿裡“雲服務器ECS”,這一個服務器就夠了,這個服務器及可以配置IIS發布站點也可以安裝數據庫,用這一個就夠了。
後期,數據明顯數據量劇增,就需要使用“阿裡雲數據庫RDS”,使用MySQL數據庫會比SQL Server 每個月的使用費用便宜一點,畢竟MySQL開源嘛,所以,推薦使用MySQL數據庫。所以,最開始做項目的時候,就推薦使用MySQL數據庫。
上面說了,一開始部署的時候不用租用“阿裡雲數據庫RDS”;購買完以後,會給你服務器IP,自己設置賬號密碼以後,就可以在自己電腦上進行遠程操作啦;在服務器中發布站點和在自己電腦發布站點的步驟一樣,沒有什麼特殊的。
遠程操作:
開始菜單那輸入 mstsc;輸入賬號密碼即可。
這一部分主要由兩部分組成:
接口的編寫(VS 2013 的.NET平台WCF技術)接口的部署(IIS)
本人第一次接觸WCF技術的時候,是由一位在職場工作多年的技術經理告訴我的,也就是他帶領我完成了今年五月份的項目。
要做好WCF部分工作,要注意一下幾個方面:
什麼是WCF技術?怎麼創建一個WCF工程?怎麼調試和運行一個WCF工程?WCF怎麼和數據庫建立鏈接?怎麼配置數據庫服務器的連接地址(也就是IP)?返回值用什麼樣的規范?如何編寫返回值?這個大家自己百度就好了,我就不抄襲別人的東西了。其實,我沒管那麼多,能用就行。
這個,也來一個傳送門吧!( 傳送門:新建WCF項目)
在上面的博客連接中已經有說明,這裡在強調一下。F5快速調試。(就是這麼厲害)
其實,WCF和SQL Server 還是很好連接的,畢竟都是微軟自家東西
不過,按照上面的方式,就把數據庫的連接字符串寫在程序內部了,如果服務器IP地址改變,或者更換服務器的時候,就需要重新打開原項目工程進行IP地址的修改(最終的編譯結果會生成一個dll文件),這是一件我們不願意做而且很麻煩的事情,所以,要注意,把連接字符串寫在web.config文件中。這樣就可以靈活的修改IP地址。
對於WCF而言,返回值都是用JSON串的形式返回的,所以,對於一般的查詢結果我們可以自己拼接出來返回一個狀態值。
例如:如果驗證這個用戶是否合法,就可以返回
{"State" :1}表示合法;{“State” :0}表示不合法;{“State” :2}表示服務器異常。當然,你還可以選擇自己增加更多的內容。例如:
{“UserID” :10001 , "Token" : "8fc043eb-0722-4c11-a0f4-8b9194066a35"} //返回用戶ID和令牌(GUID)。只要把你想要返回的東西以JSON格式返回就可以了,剩下的就是Android客戶端的調用。如何調用,我們會後續講解。
對於WCF返回JSON格式,有一個現成的dll文件,直接引用即可。
其實,對於這樣的項目工程而言,接口的發布之前還需要Android端和接口在線調試。也就是說,一個人開打VS2013,另一個人打開ADT,面對面直接調試,這樣VS端的可以打斷點,當Android端的調用接口的時候,VS會自動停在斷點處,這樣調試和查看參數更加方便。(這個沒有找到對應的傳送門,後面講解)
本節三部分組成:
IIS環境配置在線調試接口發布在調試和接口發布之前,一定要配置好IIS環境。
關於IIS環境的配置,推薦兩個博客結合安裝( 傳送門:IIS部署和WCF發布IIS部署)
這兩個博客把WCF發布的內容也講述了,其實,現在還沒有到發布的時候,此時需要的是IIS配置好以後,進行在線調試,等一切都調試通過以後,就可以發布了。
這個沒有找到合適博客,在這裡,本人說明一下。
按照上面的步驟,打開IIS配置文件。
在VS調試的時候,你就可以知道自己的調試端口號是什麼,然後就“ctrl + F”找到對應的端口即可,賦值當前行,把localhost改為本機IP地址,保存,關閉。
如圖,按照序號操作,為了簡化文章長度,我把最後的顯示結果截成此圖,實際上,三個窗體的顯示順序整好與現在的層級顯示關系相反。
剩下的就不說了,百度上有打開防火牆端口的教程
只需要把localhost修改為本機IP即可。
通過以上步驟,Android客戶端就可以訪問這個連接了。也就是,同一個局域網的用戶,都可以訪問這個網站了。
剩下的工作就是在線調試。
這個接口發布和上面的調試有什麼區別呢?
這個問題問的好。
上面的調試是在VS打開的情況下才可以訪問,而且端口號是VS自己確定的;此時的發布完全由自己控制,就是自己發布一個網站的過程,端口號(如果和上面的端口號不一樣,要打開防火牆端口號)可以任意設置,而且不打開VS也可以訪問網站。在上文中已經發過博客鏈接,在這裡,再發一次
還有一點值得說明,在自己發布接口的根目錄下,新建一個文件夾,用於存放簽名且加固好的APK,以此來提供用戶下載。
但是,在網頁中,下載APK需要一些站點的設置
此部分分為兩部分設計:
基本的界面設計和控件使用觸發事件的響應;服務器接口調用。不同軟件類型的開發,使用的界面控件和布局效果肯定大不一樣,所以,在這裡,只說明本人在制作軟件過程中使用到的相關技術和知識。
例如,當用戶登陸過apk以後,肯定不希望下一次登錄的時候還輸入賬號密碼等信息,所以,此時需要把用戶輸入的數據進行本地存儲,安卓平台有五種數據存儲方式,我使用的是“用SharedPreferences存儲數據”。這個相對簡單,而且只是三兩個數據,這個足夠了
// 保存登錄數據:賬號,密碼,ID,令牌 到 data 文件中 SharedPreferences sp2 = (LoginActivity.this).getSharedPreferences("data",MODE_PRIVATE); SharedPreferences.Editor editor = sp2.edit();// 獲取編輯對象 //editor.clear(); editor.putString("USERID", uid); editor.putString("PASSWORD", psw_md5.getMD5(psw)); editor.putInt("ID", id); editor.putString("TOKEN", token); editor.commit();// 提交保存修改
// 用戶退出,清空data中的數據 SharedPreferences sp = ExitActivity().getSharedPreferences("data", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit();// 獲取編輯對象 editor.clear(); editor.commit();// 提交保存修改
這個技術在安卓開發中利用的最多了,縱觀網上各種做法
如何監聽ListView的滾動事件?如果內容滑動到最底部,如何加載新數據?
在網上發現了這篇文章,感覺不錯,大家可以看看。
其實,ListView加載數據的事件就是這個,在loadData()的地方寫好自己的數據加載代碼即可。
listview.setOnScrollListener(new OnScrollListener() { //AbsListView view 這個view對象就是listview @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) { if (view.getLastVisiblePosition() == view.getCount() - 1) { loadData(); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { lastItem = firstVisibleItem + visibleItemCount - 1 ; } });
這才是,重點!!!
對於WCF這樣的服務器接口,一般來說,推薦使用KSOP。這個還是跟簡單的,在服務器中,包含很多接口,那麼在自己的客戶端上,你就對應設計每個接口即可。
不過,我還是貼一段代碼,來顯示一下我認為的規范開發。
package com.DLMU.freeride.WCFService; import java.io.IOException; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import org.xmlpull.v1.XmlPullParserException; import android.util.Log; public class Services { private static String NameSpace = "http://tempuri.org/"; private static String URL = "http://你的IP:端口號/Service1.svc"; private static String MethodName_login = "login"; public String Login(String phonenum, String password) { String methodName = MethodName_login; // 指定WebService的命名空間和調用的方法名 SoapObject soapObject = new SoapObject(NameSpace, methodName); // 設置需調用WebService接口需要傳入的參數token soapObject.addProperty("phonenum", phonenum); soapObject.addProperty("password", password); // 生成調用WebService方法的SOAP請求信息,並指定SOAP的版本 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); envelope.bodyOut = soapObject; // 設置是否調用的是dotNet開發的WebService envelope.dotNet = true; // 等價於envelope.bodyOut = rpc; envelope.setOutputSoapObject(soapObject); HttpTransportSE trans = new HttpTransportSE(URL); trans.debug = true; // 使用調試功能 try { // 調用WebService String SOAP_ACTION = "http://tempuri.org/IService1/" + methodName; Log.d("WCF", SOAP_ACTION); trans.call(SOAP_ACTION, envelope); } catch (IOException e) { System.out.println("IOException"); e.printStackTrace(); } catch (XmlPullParserException e) { System.out.println("XmlPullParserException"); e.printStackTrace(); } // 獲取返回的數據 SoapObject result = (SoapObject) envelope.bodyIn; // 獲取返回的結果 String json = null; if (result == null) { json = "接口調用失敗"; } else { json = result.getProperty(0).toString(); } Log.d("WCF", json); return json; } }
// 設置需調用WebService接口需要傳入的參數token soapObject.addProperty("phonenum", phonenum); soapObject.addProperty("password", password);
如果你認為,編寫完對象中的方法就能直接調用,那你就錯了。使用接口函數的時候還要注意一點。見代碼
try { Thread thread = new Thread(new Runnable() { @Override public void run() { Services s = new Services(); String result = s.Login(uid, psw); if (result.length() >= 12) { //在我的接口中,定義{"State":0},表示賬號密碼錯誤,長度為11 //合法用戶應該返回:{“UserID” :10001 , "Token" : "8fc043eb-0722-4c11-a0f4-8b9194066a35"},長度大於11 //所以用12來做比較 // 身份合理,正確跳轉 Intent intent = new Intent( LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } else { Looper.prepare(); Toast.makeText(LoginActivity.this, "賬號或密碼錯誤", Toast.LENGTH_SHORT) .show(); Looper.loop(); } } }); thread.start(); } catch (Exception e) { e.printStackTrace(); }
到此,接口的工作就完成了,因為接口返回的數據格式是JSON串,所以,需要在客戶端進行JSON串解析。
//{ // [{"ID":1,"TEL":"123456"}], // [{"ID":2,"TEL":"123457"}], // [{"ID":3,"TEL":"123458"}], // [{"ID":4,"TEL":"123454"}] //} JSONTokener jsonTokener = new JSONTokener(data); JSONArray array = (JSONArray) jsonTokener.nextValue(); for (int i = 0; i < array.length(); i++) { // 提取數據 JSONObject item = array.getJSONObject(i); int id = item.getInt("ID"); String tel = item.getString("TEL"); }
根據上面的例子,我對於一個JSON串,如果遇到{[],[],[]},我們需要先使用JSONArray;如果遇到{},我們使用JSONObject來獲取數據。
至此,教程結束。
隨著Android5.0的發布,google帶來了Material Design,俗稱:材料設計。並帶來了一些新的東西,這裡就一一介紹這些新的設計元素。 1、P
一.App劫持病毒介紹App劫持是指執行流程被重定向,又可分為Activity劫持、安裝劫持、流量劫持、函數執行劫持等。本文將對近期利用Acticity劫持和安裝劫持的病
最近自家的系統要做一個升級服務,裡面有三個功能,第一個是系統升級,也就是下載OTA包推送到recovery裡升級的,而第二個是MCU升級,這就涉及到我們自家系統的一些情況
在Android開發中,經常需要加載顯示網頁,一般一個頁面在打開後,在等待數據加載的過程中,都需要花一點時間,這個時候往往需要顯示一個轉動的進度條(ProgressBar