和之前的內(nèi)容一樣,Android簡易打地鼠卵慰,也是通過小軟件的方式來鞏固android知識
先看下效果缩歪,其實主要就一張圖,但是設(shè)計到的知識點還是很多的
應用介紹:
一個相對比較簡單的天氣預報項目罩句,涉及兩個界面焚刺,主界面用于顯示當日天氣和后5天的天氣情況,點擊搜索會進入添加城市界面门烂, 該界面僅有 一個輸入框乳愉,輸入城市后再次點擊搜索會返回到主界面,并根據(jù)輸入的城市信息進行數(shù)據(jù)更新诅福。點擊更新則會刷新當 前數(shù)據(jù)匾委,由于應用目前沒有添加本地保存的功能,如果添加的話氓润,應該會采用SharedPreferences將選擇的城市對應的編碼保存到本地(之前的Android簡易老虎機就是使用這個保存游戲數(shù)據(jù))赂乐,這樣在每次打開軟件的時候先讀取本地保存信息并進行相應更新,如果沒讀取到咖气,則默認為顯示武漢的天氣
涉及到的知識點:
首先是HTTP請求挨措,因為需要從網(wǎng)絡(luò)獲取天氣數(shù)據(jù),采用的是HttpURLConnection崩溪,同時將獲取到的天氣信息轉(zhuǎn)化為字符串 浅役,小結(jié)如下
1.new一個URL的對象,并傳入目標網(wǎng)址
URL url = new URL("http://www.baidu.com");
2.使用URL對象開啟連接伶唯,并轉(zhuǎn)型為HttpURLConnection
HttpURLConnection connection = (HtttpURLConnection)url.openConnection();
3.設(shè)置HTTP的請求方法GET或者POST
connection.setRequestMethod("GET");
4.設(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ù)進行解析瞪讼,得到所需的天氣信息 **
json數(shù)據(jù)的格式:
{ }中包含的即為JSON對象, [ ]代表JSON對象的數(shù)組 钧椰,里面可以存放一系列JSON對 象,如: [{ "name":"tom", "age":"20" }]
一般可能在 [ ] 前面還有一個字符串 比如 information :[ ]
在解析時,要到達 [ ] 里面開始解析
1.JSONObject rootObject = new JSONObject(dataStr); // 得到數(shù)據(jù)的根對象
2.JSONObject json = rootObject.getJSONObject("information"); //取出 information中的值
3.然后直接使用 json.getString(" key "); //key為對應數(shù)據(jù)的鍵符欠,就可以得到對應的數(shù)據(jù)
**在子線程中更新界面天氣信息嫡霞,界面中間當日天氣顯示較為詳細,后5天的天氣放在一個HorizontalScrollView中希柿,實現(xiàn)水平滾 動查看天氣信息 **
**更新是為ImageView設(shè)置監(jiān)聽器诊沪,點擊后會啟動一個動畫,即更新圖標的轉(zhuǎn)動曾撤,該處是采用了Animation來實現(xiàn)圖標的轉(zhuǎn)動動畫端姚, 動畫開啟后使用一個Handler對象的延時操作,在1s后關(guān)閉該動畫盾戴,也就是說每次點擊寄锐,理論上圖標都會轉(zhuǎn)動1s然后停止 **
new Handler().postDelayed(new Runnable(){ @Override public void run(){ //要執(zhí)行的操作 } },delayedTime)
點擊搜索后進入添加城市界面,目前只能手動輸入城市名尖啡,采用的是在程序內(nèi)部放置了包含城市名和對應的城市編號的XML文件橄仆, 所以自然需要使用到XML解析,本次使用的是pull解析衅斩,在進入添加城市界面后盆顾,系統(tǒng)會首先獲取到所有的城市信息,即解析XML 數(shù)據(jù)畏梆,解析到的數(shù)據(jù)是采用鍵值對的方式放入到Map中進行存儲的您宪,城市名為鍵,城市編號為值奠涌,在輸入正確的城市后宪巨,點擊搜 索會返回到主界面,同時根據(jù)輸入的城市名(鍵)溜畅,獲取到對應的城市編號(值)捏卓,該處用到了回值傳遞,在返回到主界面的同 時則會把城市編碼傳遞過來慈格,并根據(jù)獲取的城市編碼重新通過HTTP連接獲取到新的數(shù)據(jù)怠晴,并進行更新
使用pull解析
1.首先構(gòu)建一個pull解析器工廠
XmlPullParserFactory factory =XmlPullParserFactory.newInstance();
2.從工廠中構(gòu)建一個pull解析器
XmlPullParser parse= factory.newInstance();
3.設(shè)置輸入信息 parse.setInput(is, "UTF-8");
其中is是一個輸入流對象,當然可以通過getAssets().open("file");
打開資產(chǎn)文件中的文件以獲得一個輸入流對象
4.定義一個事件類型int eventType = parse.getEventType();
5.開始遍歷XML浴捆,得設(shè)置一個while循環(huán)蒜田,只要事件類型不是結(jié)束的事件類型,那么一直讀取
while(eventType != XmlPullParser.END_DOCUMENT){ }
6.在上面的循環(huán)中開始讀取选泻,得設(shè)置一個判斷冲粤,判斷當前讀取的標簽是否是開始標簽
if(eventType == XmlPullPaser.START_TAG){ }
7.當上訴判斷的是開始標簽美莫,即說明已經(jīng)開始讀取正文部分,此時應該定義一個字符串用于表示讀取的標簽的標識
String tag = parse.getName();
這時需要設(shè)置一個判斷色解,用于確認標簽的標識是包裹所需數(shù)據(jù)的標簽
if(tag.equals("key")){ //假設(shè)此處的key是XML中的包裹所需數(shù)據(jù)的那個標簽 String key = parse.nextText(); //由名字也可以看出來茂嗓,nextText(),該標簽下一位的文本餐茵,也就是數(shù)據(jù)了 }
8.可以把parse理解為一個游標吧科阎,注意上面的問題,判斷如果是包裹所需數(shù)據(jù)的標簽忿族,那么讀取它下一位的文本數(shù)據(jù)锣笨,但是一般不會只有一個數(shù)據(jù),所以還是得繼續(xù)讀取道批,為了循環(huán)讀取错英,那么在當前數(shù)據(jù)讀取后,游標應該往下再移動一位,同時更新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文件夾時隆豹,把它建在了res目錄下椭岩,結(jié)果總是讀取不到XML文件對應的信息,以為是解析代碼寫錯了璃赡,但是系統(tǒng)并沒報任何錯誤判哥,折騰好久才發(fā)現(xiàn)是這個問題,應該和res放置在同等位置
小結(jié):這次的相比之前的小軟件碉考,主要就是涉及到了網(wǎng)絡(luò)和數(shù)據(jù)解析塌计,源碼放在GitHubWeather ,當然了,肯定還是有不少缺陷的侯谁,希望有興趣的童鞋一起改正一起進步哈