日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式軟件
[導讀] 注:本文來自友盟-安卓巴士教程大賽第一名獲獎作品,作者安卓巴士的ID為liupeinye。推薦給所有剛剛開始接觸Android開發(fā)的朋友們!本文面向Android初級開發(fā)者,有一定的Java

 注:本文來自友盟-安卓巴士教程大賽第一名獲獎作品,作者安卓巴士的ID為liupeinye。推薦給所有剛剛開始接觸Android開發(fā)的朋友們!

本文面向Android初級開發(fā)者,有一定的Java和Android知識即可。

文章覆蓋知識點:HttpWatch抓包,HttpClient模擬POST請求,Jsoup解析HTML代碼,動態(tài)更新ListView

背景介紹:客戶端(Client)或稱為用戶端,是指與服務器相對應,為客戶提供本地服務的程序。而android系統(tǒng)上的90%客戶端軟件都有一個共性,就是為了改善網頁在android系統(tǒng)上體驗不佳而生,最具有影響力的軟件有:新浪微博、人人網、淘寶等,這類軟件最突出的特點就是,先有網站再有軟件。由于網絡技術發(fā)展的多樣性,手機瀏覽器往往無法跟隨它的步伐,為改善用戶體驗,網站客戶端軟件印運而生。

以下內容100%原創(chuàng),并在安卓巴士論壇首發(fā),如需轉載,請注明作者和出處。謝謝合作。

開發(fā)Android網站客戶端通常有兩種方法:第一種,通過服務端的開放平臺,調用提供的API接口來開發(fā),比如說open sina;第二種,服務端沒有提供任何接口,你也沒有服務端任何數(shù)據(jù)庫訪問權限,就是一個純純粹粹的網站,要你做客戶端。今天,我要和大家分享的正是第二種情況。

這是一個簡單的示意圖,告訴我們,數(shù)據(jù)是由網頁從數(shù)據(jù)庫中取出,我們要為這個系統(tǒng)做客戶端,我們就應該這樣去改造它。

通過這樣間接的方法來訪問數(shù)據(jù)庫,只要網頁能看到的內容,我們的客戶端都能獲取到,而UI是由你自行制作,就可以使使用體驗上一個臺階。

既然網頁是我們的數(shù)據(jù)樞紐,我們就從網頁分析著手。

該教程來自本人項目-掌上民大-真實經驗,所以用項目中的”掌上圖書館”板塊來示范。

該項目任務為中南民族大學圖書館圖書查詢功能制作客戶端。

首先打開該網址http://www.lib.scuec.edu.cn/,我們會看到主界面

正中間就是查詢入口,我們輸入”android”進行查詢

得到結果的網頁,但我們能發(fā)現(xiàn),這個頁面是ILAS圖書管理系統(tǒng),所以真正的入口并不是上面紅圈的地方。

所以我繼續(xù)找,經過短暫的觀察,發(fā)現(xiàn)入口在這里

我們點擊進入

果然就是這貨,我們點擊書目查詢

就是它了。真正的入口就在這里,這時我們打開HttpWatch軟件,點”Record”,在搜索框里輸入”android”,點擊查詢,抓取以”android”為關鍵字搜索時瀏覽器的所有包。待結果界面載入完成后,HttpWatch上就會出現(xiàn)如下信息

我們先看Summary選項卡,我們可以初步了解,這是一個POST請求(Http請求中的一種,另一種是GET),POST到的網址是http://coin.lib.scuec.edu.cn/cgi-bin/IlaswebBib。

這樣我們的思路就清晰了,我們的客戶端需要模擬瀏覽器,向上述地址POST一個包,那個地址肯定會返回一個Content給我們,不出意外的話,Content里面就是我們要的書目信息。那么,瀏覽器POST上去的內容是什么呢?我們點擊這條POST請求,看詳細信息,

由于是POST請求,我們先看POST DATA,里面是以鍵值對的形式存儲的,這里顯示了我們?yōu)g覽器在我們搜索”android”時,POST的所有數(shù)據(jù)。那這些鍵值對又代表了什么呢,我們打開這個網頁的源碼來一探究竟。

從這段可以看出v_index是表示查找途徑的它有TITLE,AUTHOR,SUBJECT,CLASSNO,ISBN,CALLNO六種值

FLD_DAT_BEG和FLD_DAT_END分別是開始和結束年份

v_value表示用戶在搜索框中輸入的內容

v_paggnum表示每頁顯示的書目條數(shù),有10 15 20三種

v_seldatabases是檢索庫 有0 1 2三種值v_LogicSrch是檢索方式 有0 1兩種值[!--empirenews.page--]

Submit是查詢或重填,有 查 詢 和 重 填 兩種值

至此,我們弄清楚了POST Data里所有內容的含義和取值可能。但我們模擬POST請求為什么,其實就是為了得到搜索的書目信息,所以我們看一下返回的Content是不是我們要的東西

果然,就是我們搜到的書目信息,就以String的形式放在Content里面。最后我們查看一下Stream,截圖,以防等下我們需要這里面的東西

好了,這個頁面的工作原理我們已經弄清楚了:用戶在網頁中輸入搜索內容后,點擊查詢,瀏覽器會POST一個Data到目標網址,該網址的返回信息就是搜到的書目。

我們開始編寫代碼,模擬這個過程,先打開eclipse建立一個Java項目(注意是Java項目,因為Java項目可以完美移植到Android項目中且調試方便,并且模擬Http請求這一過程沒有用到任何Android功能)。

導入HttpClient的4個包commons-codec、commons-httpclient、commons-logging、log4j。

//實例化HttpClient

HttpClient client = new HttpClient();

//Stream頁面里面有Host地址 端口是80

client.getHostConfiguration().setHost("http://coin.lib.scuec.edu.cn", 80);

//用目標地址 實例一個POST方法

PostMethod post = new PostMethod("http://coin.lib.scuec.edu.cn/cgi-bin/IlaswebBib");

//將需要的鍵值對寫出來

NameValuePair beg = new NameValuePair("FLD_DAT_BEG" , “”);

NameValuePair end = new NameValuePair("FLD_DAT_END" , “”);

NameValuePair submit = new NameValuePair("submit" , "查 詢"));

NameValuePair vIndex = new NameValuePair("v_index" , “TITLE”);

NameValuePair vLogicSrch = new NameValuePair("v_LogicSrch" , "0");

NameValuePair vPagenum = new NameValuePair("v_pagenum" , "10");

NameValuePair vSeldatabase = new NameValuePair("v_seldatabase" , "0");

NameValuePair vValue = new NameValuePair("v_value" ,”android”);

//給POST方法加入上述鍵值對

post.setRequestBody(new NameValuePair[] {beg , end , submit , vIndex , vLogicSrch , vPagenum , vSeldatabase , vValue});

//執(zhí)行POST方法

client.executeMethod(post);

//將POST返回的數(shù)據(jù)以流的形式讀入,再把輸入流流至一個buff緩沖字節(jié)數(shù)組

//StreamTool類是我自己寫的一個工具類,其內容將在下文附出

byte[] buff = StreamTool.readInputStream(post.getResponseBodyAsStream());

//將返回的內容格式化為String存在html中

String html = new String(buff);

//任務完成了,釋放連接

post.releaseConnection();

//StreamTool類如下

public class StreamTool {

/**

* 從輸入流中獲取數(shù)據(jù)

* @param inputStream 輸入流

* @return 字節(jié)數(shù)組

* @throws Exception

*/

public static byte[] readInputStream(InputStream inputStream) throws Exception

{

//實例化一個輸出流

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

//一個1024字節(jié)的緩沖字節(jié)數(shù)組

byte[] buffer = new byte[1024];

int len = 0;

//讀流的基本知識

while ((len=inputStream.read(buffer)) != -1) {

outputStream.write(buffer, 0, len);

}

//用完要關,大家都懂的

inputStream.close();

return outputStream.toByteArray();

}

}

現(xiàn)在,我們得到了POST方法返回的String,我們輸出到控制臺看看是什么

System.out.println(html);

沒錯,就是我們上文看到的HttpWatch 抓到的返回Content,也就是一段HTML代碼,這說明,我們模擬瀏覽器POST請求成功了!

我們再試試別的搜索內容,來一個”android開發(fā)”(即將v_value鍵值對的值改成”android開發(fā)”),這時運行后,我們卻從控制臺得到了這樣的結果:

經過幾次試驗后,發(fā)現(xiàn)一個規(guī)律,只要搜索內容中包括中文,就搜不到。

所以可以判定是中文編碼的問題,(在開發(fā)這類客戶端時候,中文編碼往往是個很具困難的問題。安卓巴士開發(fā)3群的某群友提到:服務器交流用的編碼是”ISO-8859-1”,跟我起初用到的編碼一致,但真實性仍需考證)所以我們修改上面的代碼,將代表搜索內容的v_value對應的值編碼為”ISO-8859-1”

就將上段代碼中的

NameValuePair vValue = new NameValuePair("v_value" ,”android”);

改為

NameValuePair vValue = new NameValuePair("v_value" , new String(“android開發(fā)”.getBytes(),"ISO-8859-1"));[!--empirenews.page--]

這時再運行,控制臺成功輸出以” android開發(fā)”為關鍵字的Content。

至此,我們POST請求才真正完成。 觀察控制臺的HTML后發(fā)現(xiàn),我們需要的書目信息就在里面,只不過被一些HTML標簽包裹住了,下一步我們就要解放這些信息,存儲到容器里。

這里我們要用到Jsoup,一個Java開源HTML解析器(來自org.jsoup包)。

我們直接上代碼,逐行解釋(大家最好對應上面的HTML代碼來理解)

首先我們建一個容器來裝這些解析到的數(shù)據(jù),由于我的項目是將這些數(shù)據(jù)以ListView呈現(xiàn)給用戶,而ListView的數(shù)據(jù)是由Adapter提供,Adapter需要傳一個特殊容器-包含HashMap的ArrayList(Android基礎知識)

//所以有

List

//開始使用Jsoup

//Jsoup支援一個Document類 將剛才的html轉化成Document

Document document = Jsoup.parse(html);

//一個Document又由elements組成 我們選擇”tr”開頭的標簽,存入 trs元素群中

Elements trs = document.select("tr");

//得到整個HTML中包含tr的標簽的個數(shù)

int totalTrs = trs.size();

//我們可以觀察上面沒有搜索結果的那個HTML。發(fā)現(xiàn),如果totalTrs<=3就表示沒結果。

//只要有書目結果totalTrs必定大于3,于是

if(totalTrs > 3)

for(int i = 0;i < totalTrs – 3;i++)

{

//觀察HTML,從第i+2個tr開始,包含的才是我們要的書目信息

//我們從每個tr中選出td標簽元素群

Elements tds = trs.get(i + 2).select("td");

//得到每個tr中td的個數(shù)

int totalTds = tds.size();

//一個臨時的HashMap,里面是String-Object鍵值對

Map

//j是一個標識數(shù)

for(int j =0;j < totalTds ;j++)

{

switch (j) {

//0表示第一個,即書名

//put方法即向map加入一條鍵值對

//html()方法就得到標簽括起來的內容

case 0:

map.put("book_title", tds.get(j).html().toString());

break;

case 1:

//1表示第二個,即作者

map.put("book_author", tds.get(j).html().toString());

break;

case 2:

//2表示第三個,即出版信息

map.put("book_press", tds.get(j).html().toString());

break;

case 3:

//3表示第四個,即頁數(shù)

map.put("book_page", tds.get(j).html().toString());

break;

case 4:

//4表示第五個,即價格

map.put("book_price", tds.get(j).html().toString());

break;

case 5:

//5表示第六個,即索取號

map.put("book_noFor", tds.get(j).html().toString());

break;

case 6:

//6表示第七個,即那段網址

//那段網址td中又包含一個a標簽,a標簽的href屬性的值就是網址

//attr(“href”)可以返回href屬性的值

map.put("book_detail", tds.get(j).select("a").attr("href").toString());

break;

default:

break;

}

}

list.add(map);

}

list就是我們需要的ArrayList啦

上面所有代碼調通后,我們只需一些簡單的復制粘貼,就可以放在我們的Android工程中,加上一段簡單的代碼就可以讓ListView顯示這個ArrayList。(由于沒有任何技術含量,以及該項目暫未上線,此段代碼不予以展示,敬請諒解)

接下來,我們一個頁面最多只包含10個書目信息,而我們校圖書館,光以”Java”為關鍵字的書就超過1000本,怎么來顯示完全呢,一次顯示所有的書肯定不現(xiàn)實。首先數(shù)據(jù)量太大,手機無法承受;消耗流量過大,用戶體驗極差。所以,我們就需要ListView能夠動態(tài)加載數(shù)據(jù),即一開始顯示十項,如果用戶此時拉動ListView顯示完十項之后,自動聯(lián)網,再加載十項(如果還有十項的話),這樣的用戶體驗會非常順暢。

這個功能的核心是,我們的ListView需要實現(xiàn)OnScrollListener接口。

如果你的ListView所在的Activity繼承的是ListActivity的話,只需在extends ListActivity后面加上implements OnScrollListener,這時你需要復寫onScroll和onScrollStateChanged。如果你的ListView是從XMLgetView 得到的,你只需為它setOnScrollListener,也會需要你復寫onScroll和onScrollStateChanged。

不管你用哪種方法,我們只用修改onScroll方法

@Override

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

// TODO Auto-generated method stub

//關鍵的判斷代碼,這句話表示用戶將ListView拉至最底部

if(firstVisibleItem + visibleItemCount == totalItemCount)

//你只需要把繼續(xù)得到下面十項的代碼寫在這里,就可以實現(xiàn)上述功能了。

//同樣再使用一次POST方法,不再贅述

//代碼由于同樣原因不予以展示,敬請諒解

至此,文章開頭的幾個知識點已經全部講解完畢,時間倉促,事物繁忙,可能會影響文章質量,還請大家多多包涵。 如果有問題,可以直接回帖、發(fā)論壇信息或通過Email:anliupeinye@gmail.com聯(lián)系我。

項目成品展示:

看看這些信息是不是就是上面用網頁以"android"為關鍵字搜索到的?

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據(jù)LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉