Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK

使用Volley創建一個火星天氣應用

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called An Introduction to Volley.
An Introduction to Volley

Chinese (Traditional) (中文(繁體)) translation by Stypstive (you can also view the original English article)

Final product image
What You'll Be Creating

在這篇文章中,我會演示一個從前一篇文章 中學到的有關Volley的使用案例。 我們將創建一個火星天氣的應用,使用{MAAS} API公開的探索者號蒐集的數據。

首先,我們在Android Studio中配置好項目,並設計好用戶界面。 然後使用Volley完成應用的核心部分。 因為每個漂亮的應用往往都有一些特色圖片,所以我將演示如何使用 Flickr的api獲取一張隨機圖片。 我們將使用Volley來下載圖片,主要是考慮到其強大的緩存系統。 最後我們將添加一些漂亮的細節讓app看起來 更美觀。

1. 項目設置

首先,在Android Studio中創建一個新的項目。 因為Volley是向後兼容的,所以你可以選擇任意級別的api。 我選擇的是API 21,不過只要api在8(Froyo) 以上應該都是很ok的。

第一步: 用戶界面

我們的應用只有一個簡單的Activity。 直接使用Android Studio建議的MainActivity.java。 打開佈局編輯器,雙擊activity_main.xml

因為屏幕70%的範圍都被圖片佔用,剩下的部分是天氣信息,所以我們要使用xml的layout_weight屬性。 你當然也可以使用絕對值,但是不同的 設備值是不同的。 如果使用一個絕對的值,在很小的設備上圖像可能是90-10的比率,在較大的設備上可能是70-30甚至60-40的比率。 而layout_weight屬性可以解決這個問題。

在裡面的第一個child中,添加ImageView

在第二個RelativeLayout中,我們添加了幾個TextView元素。 其中兩個分別顯示平均溫度與天氣狀態。 第三個是顯示錯誤信息的標籤。

現在佈局已經完成了。 如果你願意,可以自己添加更多的詳細信息,但是複雜和詳細的用戶界面並不在本教程的範圍之內。

第二步: 主題和權限

在開始深入應用的核心功能之前,還要先處理兩個事情。 1.將繼承的主題改成android:Theme.Material.Light.NoActionBar。 這樣我們就不必在運行時隱藏actionbar。

最后,在項目的manifest中添加網絡權限。

2. 應用核心

第一步: 導入Volley

正如我在上篇文章中講述的,使用Volley最簡單且可靠的方式是將library作為一個module導入。 下載library的 源代碼 ,通過File > New > Module將其導入,然後在 build.gradle文件中告訴compiler把它包含在項目中。

第二步: 實現幫助類

上篇文章我們已經指出了,如果你想發起多個請求,最好使用共享的請求隊列。 要避免每次佈置一個請求都使用Volley.newRequestQueue來創建一個新的隊列,因為我們不想看到內存洩漏或者其他的問題發生。

為 了達到這個目的,你首先需要創建一個使用了單例模式的類。 這個類被作為靜態的,全局的對象引用,然後由它處理RequestQueue對象。 這樣,整個應用中就只有一個RequestQueue。 接下來,繼承Application類,你需要告訴系統在應用啟動的時候創建這個對象,這個過程甚至發生在第一個Activity創建之前。

因為我們是在安卓系統中,所以我們要簡單的修改一下常規單例模式的結構。 這個類需要在Application.onCreate方法中創建一個自己的實例 -而不是在常規的getInstance方法中判斷它為null的時候產生一個實例。

為此,我們創建一個繼承自Application類的MarsWeather.java類, 重寫onCreate方法,初始化這個靜態實例的RequestQueue對象。

在這個單例類中,我們使用一個公共synchronized方法getInstance來構造類的對象。 在getInstance方法內部,返回一個mInstance變量。 onCreate是在應用啟動的時候觸發,因此mInstance變量在getInstance方法被調用的第一時間就已經設置好了。

接下來,在AndroidManifest.xml文件中告訴系統你想讓MarsWeather在應用啟動的時候被加載, 在application標籤下,如下添加屬性名稱

好了. 一個Application類的實例就創建好了,它甚至要比MainActivity都要先創建。 除了那些標準的操作,比如調用super.onCreate,onCreate還產生了一個RequestQueue的實例。

我們還需要實現另外三個方法才能完成這個幫助類。 直接返回在onCreate中實例化了的 mRequestQueue。 我們還需要一個添加請求到隊列的方法add,以及負責取消請求的方法cancel。 這三個方法實現如下:

TAG是一個用於識別請求的標記。 在這個例子中,可以是任意值:

第三步: 實現自定義的Request

正如你已經知道的,Volley提供了三種標準的請求類型:StringRequest, ImageRequest, 和 JsonRequest。 我們的應用將使用後那兩個去獲取天氣數據和隨機圖片列表。

默認情況下,Volley將請求的優先級設置為普通。 一般這也沒什麼問題,然而在我們的應用 中,兩種請求的差別很大,有必要讓它們在隊列中有不同的優先級。 獲取天氣數據的優先級要比獲取隨機圖片的高。

因此我們需要自定義JsonRequest 類。 創建一個繼承自JsonObjectRequestCustomJsonRequest.java, 然後如下重寫getPriority方法。

第四步: 獲取數據

接下來總輪到算到了教程最有趣的部分-獲取天氣數據。 請求的後端地址是:

這個api是可以直接瀏覽的,那我們打開這個鏈接查看返回的JSON結果。 這個JSON包含了一個簡單的數據對象,由一些列的字符串組成,從溫度到風向以及日落時間。

我們首先在MainActivity类中聲明以下的變量:

你可以在onCreate之外調用MarsWeather.getInstance。 既然這個類早就初始化了,你也就不必等到onStart方法執行的時候才調用它。 當然界面中的view還是需要在onCreate方法中引用。

完成這些工作之後,我們開始實現loadWeatherData方法。 我們創建了一個自定義的Volley請求並設置優先級為。 然後我們調用了幫助類的add方法將請求添加進隊列中。 最重要的其實是result listener部分,因為它將關係到用戶界面。

你可以看到,這個方法獲取了最低和最高溫度,計算了平均溫度,然後用它們更新了用戶界面。 我還實現了一個處理錯誤的簡單方法。

我們現在只需要在onCreat中調用已經完成的loadWeatherData方法 。 app現在已經可以顯示來自火星上的天氣數據了。

3. 獲取圖片數據

既然已經完成了app的核心部分,那麼我可以考慮如何讓app看起來更吸引人一些。 可以隨機的獲取一張火星圖片,然後顯示給用戶。

第一步: 獲取一張隨機的圖片

你需要一個Flickr API key來獲取一組隨機圖片。 圖片的後端地址是:

可以看到,這個請求非常簡單。 你可以告訴Flickr給你一個JSON格式的結果(format=json),但是我們並不會指定一個JSONcallback(nojsoncallback=1) 是要搜索一張圖片(method=flickr.photos.search), 並且感興趣的是和火星相關的標籤(tags=mars,planet,rover)。 可以查閱documentation 以了解關於請求URL格式的更多信息。

聲明如下變量:

接下來實現searchRandomImage方法:

可以看到Flickr發送回了一個包含圖片的JSONArray。 在這個方法中我產生了一個在0和數組大小之間的隨機數字,以隨機的從​​圖片數組中獲取一張圖片。 從數組的索引中獲取相應的item,然後根據這些指導構造一個圖片的URL。

跟前面一樣,我們需要一個處理錯誤的方法:

最後,在onCreate中調用searchRandomImage,別忘記捕獲可能出現的異常。

第二步: 顯示圖片

我們已經有了待加載的URL,可以開始顯示圖片了。 從前面的文章中,你已經學會了該如何做。

onResponse方法中我們寫入前一步的東西,總算可以處理結果了。

第三步: 每天顯示一張新的圖片

你可能已經註意到我們在應用每次啟動的時候獲取一張隨機圖片,繞過了Volley的緩存機制。 需要想辦法在一天中只顯示同一張圖片。

最簡單的辦法就是使用安卓的SharedPreferences。 先從聲明所需的變量開始:

接下來,在onCreate方法中,在調用searchRandomImage之前初始化mSharedPref

思路是在每次獲取一張新的隨機圖片的時候都保存當天的日期(其實保存的是某月的第幾天)。 當然,我們還同時保存了該天圖片的URL。 當應用啟動的時候,我們檢查在SharedPreferences中是否有當天的入口。 如果已經有匹配,我們使用保存了的URL。 反之獲取一張隨機的圖片,並在SharedPreferences中保存下URL。

相關的代碼是在searchRandomImage方法中,在定義完imageUrl之後,添加如下的代碼:

然後在onCreate方法中,mSharedPref定義之後的代碼就變成了:

好了。 應用已經完成。 可以在GitHub上免費下載本教程的完整源碼。 如果在這篇文章中遇到什麼問題可以參考完整的源碼。

小提示: 改善用戶界面

第一步: 字體

用戶界面中的字體決定了一個應用的直觀感受。 我們先從改變默認的Roboto字體開始,用更好看的字體來替代,比如 Lato light

assets文件夾下創建一個名叫fonts的文件夾。 如果你沒找到assets文件夾,你需要在java文件夾的同一級目錄下創建一個。 文件夾的結構差不多是這樣:app\src\main\assets\fonts

Lato-light.ttf拷貝到fonts文件夾中。 在onCreate方法中你需要重寫那些想使用新字體的View的默認typeface。

第二步: 透明的Status Bar

根據安卓Material Design的規範,我們可以是狀態欄透明, 這樣背景就可以透過狀態欄部分可見。

你可以通過應用主題的一點小小改動達到此目的。 如下編輯v21\style.xml

確保AndroidManifest.xml已經設置成使用這個主題:

總結

我們完成了一個漫長的旅程。 在第一篇文章中,我們討論了Volley以及應用。 這篇教程中,我們通過創建一個火星天氣應用來實踐了所學的基本知識。 你應該對Volley庫及其應用範圍都有了良好的認識。

关注我们的公众号
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.