和之前的內(nèi)容一樣,Android簡(jiǎn)易打地鼠,也是通過小軟件的方式來鞏固android知識(shí)
先看下效果,其實(shí)主要就一張圖,但是設(shè)計(jì)到的知識(shí)點(diǎn)還是很多的

應(yīng)用介紹:
一個(gè)相對(duì)比較簡(jiǎn)單的天氣預(yù)報(bào)項(xiàng)目,涉及兩個(gè)界面,主界面用于顯示當(dāng)日天氣和后5天的天氣情況,點(diǎn)擊搜索會(huì)進(jìn)入添加城市界面, 該界面僅有 一個(gè)輸入框,輸入城市后再次點(diǎn)擊搜索會(huì)返回到主界面,并根據(jù)輸入的城市信息進(jìn)行數(shù)據(jù)更新。點(diǎn)擊更新則會(huì)刷新當(dāng) 前數(shù)據(jù),由于應(yīng)用目前沒有添加本地保存的功能,如果添加的話,應(yīng)該會(huì)采用SharedPreferences將選擇的城市對(duì)應(yīng)的編碼保存到本地(之前的Android簡(jiǎn)易老虎機(jī)就是使用這個(gè)保存游戲數(shù)據(jù)),這樣在每次打開軟件的時(shí)候先讀取本地保存信息并進(jìn)行相應(yīng)更新,如果沒讀取到,則默認(rèn)為顯示武漢的天氣
涉及到的知識(shí)點(diǎn):
首先是HTTP請(qǐng)求,因?yàn)樾枰獜木W(wǎng)絡(luò)獲取天氣數(shù)據(jù),采用的是HttpURLConnection,同時(shí)將獲取到的天氣信息轉(zhuǎn)化為字符串 ,小結(jié)如下
1.new一個(gè)URL的對(duì)象,并傳入目標(biāo)網(wǎng)址
URL url = new URL("http://www.baidu.com");
2.使用URL對(duì)象開啟連接,并轉(zhuǎn)型為HttpURLConnection
HttpURLConnection connection = (HtttpURLConnection)url.openConnection();
3.設(shè)置HTTP的請(qǐng)求方法GET或者POST
connection.setRequestMethod("GET");
4.設(shè)置連接超時(shí)、讀取超時(shí)的時(shí)間等
connection.setConnectionTimeout(8000); connection.setConnectionReadTimeout(8000);
5.連接服務(wù)器 connection.connect();
6.開啟輸入流,獲得服務(wù)器返回的信息
InputStream in = connection.getInputStream();
7.使用disconnection()方法關(guān)閉HTTP連接 connection.disconection();
**使用JSON數(shù)據(jù)解析,使用JSONObject類將獲取到的JSON型數(shù)據(jù)進(jìn)行解析,得到所需的天氣信息 **
json數(shù)據(jù)的格式:
{ }中包含的即為JSON對(duì)象, [ ]代表JSON對(duì)象的數(shù)組 ,里面可以存放一系列JSON對(duì) 象,如: [{ "name":"tom", "age":"20" }]
一般可能在 [ ] 前面還有一個(gè)字符串 比如 information :[ ]
在解析時(shí),要到達(dá) [ ] 里面開始解析
1.JSONObject rootObject = new JSONObject(dataStr); // 得到數(shù)據(jù)的根對(duì)象
2.JSONObject json = rootObject.getJSONObject("information"); //取出 information中的值
3.然后直接使用 json.getString(" key "); //key為對(duì)應(yīng)數(shù)據(jù)的鍵,就可以得到對(duì)應(yīng)的數(shù)據(jù)
**在子線程中更新界面天氣信息,界面中間當(dāng)日天氣顯示較為詳細(xì),后5天的天氣放在一個(gè)HorizontalScrollView中,實(shí)現(xiàn)水平滾 動(dòng)查看天氣信息 **
**更新是為ImageView設(shè)置監(jiān)聽器,點(diǎn)擊后會(huì)啟動(dòng)一個(gè)動(dòng)畫,即更新圖標(biāo)的轉(zhuǎn)動(dòng),該處是采用了Animation來實(shí)現(xiàn)圖標(biāo)的轉(zhuǎn)動(dòng)動(dòng)畫, 動(dòng)畫開啟后使用一個(gè)Handler對(duì)象的延時(shí)操作,在1s后關(guān)閉該動(dòng)畫,也就是說每次點(diǎn)擊,理論上圖標(biāo)都會(huì)轉(zhuǎn)動(dòng)1s然后停止 **
new Handler().postDelayed(new Runnable(){ @Override public void run(){ //要執(zhí)行的操作 } },delayedTime)
點(diǎn)擊搜索后進(jìn)入添加城市界面,目前只能手動(dòng)輸入城市名,采用的是在程序內(nèi)部放置了包含城市名和對(duì)應(yīng)的城市編號(hào)的XML文件, 所以自然需要使用到XML解析,本次使用的是pull解析,在進(jìn)入添加城市界面后,系統(tǒng)會(huì)首先獲取到所有的城市信息,即解析XML 數(shù)據(jù),解析到的數(shù)據(jù)是采用鍵值對(duì)的方式放入到Map中進(jìn)行存儲(chǔ)的,城市名為鍵,城市編號(hào)為值,在輸入正確的城市后,點(diǎn)擊搜 索會(huì)返回到主界面,同時(shí)根據(jù)輸入的城市名(鍵),獲取到對(duì)應(yīng)的城市編號(hào)(值),該處用到了回值傳遞,在返回到主界面的同 時(shí)則會(huì)把城市編碼傳遞過來,并根據(jù)獲取的城市編碼重新通過HTTP連接獲取到新的數(shù)據(jù),并進(jìn)行更新
使用pull解析
1.首先構(gòu)建一個(gè)pull解析器工廠
XmlPullParserFactory factory =XmlPullParserFactory.newInstance();
2.從工廠中構(gòu)建一個(gè)pull解析器
XmlPullParser parse= factory.newInstance();
3.設(shè)置輸入信息 parse.setInput(is, "UTF-8");其中is是一個(gè)輸入流對(duì)象,當(dāng)然可以通過getAssets().open("file");打開資產(chǎn)文件中的文件以獲得一個(gè)輸入流對(duì)象
4.定義一個(gè)事件類型int eventType = parse.getEventType();
5.開始遍歷XML,得設(shè)置一個(gè)while循環(huán),只要事件類型不是結(jié)束的事件類型,那么一直讀取
while(eventType != XmlPullParser.END_DOCUMENT){ }
6.在上面的循環(huán)中開始讀取,得設(shè)置一個(gè)判斷,判斷當(dāng)前讀取的標(biāo)簽是否是開始標(biāo)簽
if(eventType == XmlPullPaser.START_TAG){ }
7.當(dāng)上訴判斷的是開始標(biāo)簽,即說明已經(jīng)開始讀取正文部分,此時(shí)應(yīng)該定義一個(gè)字符串用于表示讀取的標(biāo)簽的標(biāo)識(shí)
String tag = parse.getName();
這時(shí)需要設(shè)置一個(gè)判斷,用于確認(rèn)標(biāo)簽的標(biāo)識(shí)是包裹所需數(shù)據(jù)的標(biāo)簽
if(tag.equals("key")){ //假設(shè)此處的key是XML中的包裹所需數(shù)據(jù)的那個(gè)標(biāo)簽 String key = parse.nextText(); //由名字也可以看出來,nextText(),該標(biāo)簽下一位的文本,也就是數(shù)據(jù)了 }
8.可以把parse理解為一個(gè)游標(biāo)吧,注意上面的問題,判斷如果是包裹所需數(shù)據(jù)的標(biāo)簽,那么讀取它下一位的文本數(shù)據(jù),但是一般不會(huì)只有一個(gè)數(shù)據(jù),所以還是得繼續(xù)讀取,為了循環(huán)讀取,那么在當(dāng)前數(shù)據(jù)讀取后,游標(biāo)應(yīng)該往下再移動(dòng)一位,同時(shí)更新eventType 即
paese.next(); eventType = parser.getEventType();
總代碼:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parse= factory.newInstance(); parse.setInput(is, "UTF-8"); int eventType = parse.getEventType(); while(eventType != XmlPullParser.END_DOCUMENT){ if(eventType == XmlPullPaser.START_TAG){ String tag = parse.getName(); if(tag.equals("key")){ String key = parse.nextText(); } } paese.next(); eventType = parser.getEventType(); }
遇到的問題:在建立assets文件夾時(shí),把它建在了res目錄下,結(jié)果總是讀取不到XML文件對(duì)應(yīng)的信息,以為是解析代碼寫錯(cuò)了,但是系統(tǒng)并沒報(bào)任何錯(cuò)誤,折騰好久才發(fā)現(xiàn)是這個(gè)問題,應(yīng)該和res放置在同等位置
小結(jié):這次的相比之前的小軟件,主要就是涉及到了網(wǎng)絡(luò)和數(shù)據(jù)解析,源碼放在GitHubWeather ,當(dāng)然了,肯定還是有不少缺陷的,希望有興趣的童鞋一起改正一起進(jìn)步哈