2015年3月28日 星期六

[教學] 如何在Android Studio平台上使用Volley NetworkImageView開發?

沒寫過教學文章,這次算是第一次寫,就當作是一個使用過後的筆記好了。


為什麼要使用Volley?

1. 程式開發者只要幾行程式碼,Volley就會直接幫開發者處理好和網路通訊這一塊,而且特別擅長做頻繁的網路操作,舉凡HTTP通訊、和網站要圖等。舉例來說,當要擷取某網站的網頁原始碼然後顯示在瀏覽器上,這個「擷取某網站的網頁原始碼」的動作就很適合用Volley去做,在這個步驟裡Volley會自動幫開發者做好HTTP通訊這件事,進而拿到網頁原始碼,開發者完全不用去管底層那一塊麻煩的部分。又如當要在APP上顯示使用者的大頭貼時,「從網路上抓使用者的大頭貼」這件事也可以由Volley輕鬆完成,開發者只要幾行程式碼就搞定了。

2. 很容易和快取結合。Volley內部有一個ImageLoader,開發者可以實作(implement)它的ImageCache介面(interface)後就可以和將圖片存到快取。這邊看不懂沒差,後面有實作,總之就是幾行程式碼,看完程式碼就知道我在說什麼。那位啥要用快取?假如現在我們瀏覽了一張照片,又去瀏覽其他頁面,接下來又回來瀏覽這個照片,假如有快取的話就不用再次下載這張照片了。快取就是將之前下載過的東西先存在本機端,以手機來講就是存在手機這邊啦!簡單來說就是手機這邊已經存有備份了,這樣做不但快速又不耗費網路資源,一舉兩得。要知道,向網路抓照片其實是蠻花時間的一件事,假如每次瀏覽到這張照片都要重新和網站要照片,不但耗費網路資源,同時使用者每次都要等待圖片下載其實蠻鳥的,所以如果有快取的話這些問題都被解決了。舉個現實的例子,手機程式LINE當使用者第一次瀏覽好友列表時,每張好友照片好像都花了一些時間載入,但假如使用者去看了訊息再回來好友列表時,圖片載入的速度好像快上許多,這就是快取的實際應用。




匯入Volley到Android Studio

這是我第一次使用Android Studio開發Android APP,之前都是用Eclipse開發,所以稍微寫了一下如何在Android Studio平台上要怎麼匯入(import)資源檔這件事。

所以如果我們要用Volley這東西,首先就是要有一個Volley的資源檔嘛!請按此下載

載好了之後開啟Android Studio,先按照它預設的方式建一個專案。專案建好之後在專案目錄資料夾下會有一個app/libs/資料夾,把剛剛下載的volley.jar丟到app/libs/裡面去。接著在Android Studio左側的目錄,選擇Project,下面就會有app--libs--volley.jar,對著volley.jar按右鍵,點選Add as library即可。



點選後查看app--src--build.gradle,看看裡面的dependencies有沒有包含

compile files('libs/volley.jar')

這行,有的話匯入就搞定了。




開始寫程式

現在我們要做的事是用Volley去網路上抓一張圖,然後同時實作快取的功能。等一下出來的效果我先講一下,就是我們做出來的APP會去網路上抓一張蠻大的圖,第一次抓的時候當然後花一點時間,這是無可避免的,但當使用者第二次或第三次或之後再去瀏覽這張圖的時候,就不用花這麼多時間了,因為APP不用去網路上抓,而是直接從快取拿。

其實Volley在圖片載入這塊還有別的方法,不過在這裡先介紹我覺得最方便的方式,使用NetworkImageView。

首先,要去activity_main.xml加一串如下的代碼,加在最後的</RelativeLayout>之前即可:

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/nivTestView"
    android:layout_width="100dp"
    android:layout_height="100dp" />

activity_main.xml是MainActivity所控制的頁面,這些代碼所表示的就是在這個頁面加一個NetworkImageView,並將其長寬都設為100dp,ID設為nivTestView。

接下來在左側的目錄裡對app--src--main--java--your.package.name(你的package名稱)點擊右鍵,New一個新的Java Class取名為LruImageCache。然後把該Class內程式碼改為如下:

package your.package.name;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

public class LruImageCache implements ImageCache {

    private static LruCache<String, Bitmap> mCache;

    public LruImageCache() {
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory / 8;
        mCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        };
    }

    @Override
    public Bitmap getBitmap(String url) {
        return mCache.get(url);
    }

    @Override
    public void putBitmap(String url, Bitmap bitmap) {
        mCache.put(url, bitmap);
    }

}

請記得把第一行的your.package.name換成你自己的package名稱。

簡單來說上面這段程式碼就是在做快取的操作。在Constructor裡它限定了該快取的最大容量,在putBitmap中它將一張圖片和它原本所在url一同存入快取,在getBitmap它利用url從快取中拿到該圖片。舉個例子,當使用者第一次觀看自己的大頭貼時,會呼叫putBitmap將剛從網路上抓來的圖片存到快取去,而之後再次觀看該照片時則是呼叫getBitmap去快取拿照片而不是去網路上抓了。

現在去網路上下載一張圖到電腦裡,我們要用它來當作該ImageView的Error Image和Default Image。換而言之,當APP做好的時候,如果使用者要瀏覽這個ImageView卻還沒成功拿到圖片或是下載圖片失敗時,會取而代之顯示這張照片。現在就去網路上找張順眼的圖,並把它存成photo.PNG!接下來把照片丟到app/src/main/res/drawable/裡面去,等一下我們會用到這張照片。

接下來回到MainActivity去,裡面有一個onCreate,它是在該Activity被創建時會被呼叫。現在我在onCreate的最後加上以下程式碼:

NetworkImageView networkImageView = (NetworkImageView) findViewById(R.id.nivTestView);

RequestQueue mQueue = Volley.newRequestQueue(this);

ImageLoader imageLoader = new ImageLoader(mQueue, new LruImageCache());

networkImageView.setDefaultImageResId(R.drawable.photo);
networkImageView.setErrorImageResId(R.drawable.photo);
networkImageView.setImageUrl(YOUR_URL, imageLoader);

上面這段程式碼的意思是:

  1. 利用ID nivTestView連結剛剛在activity_main.xml所加入的NetworkImageView
  2. 建立一個RequestQueue,也就是建立HTTP要求
  3. 建立ImageLoader,把圖片操作和快取的部分搞定
  4. 設定預設照片,這邊用到剛剛下載的PNG圖
  5. 設定錯誤時顯示的照片,也是用同一張PNG圖
  6. 我們真正想用此NetworkImageView顯示的圖,第一個參數填入該圖片網址,這張圖片最好很大,例如1920x1080之類的,才可以顯著的顯現快取的神力

最最最最後,去AndroidManifest.xml加入以下代碼,一般都是加在application之前:

<uses-permission android:name="android.permission.INTERNET" />

才可以在APP中使用網路功能,小弟剛剛測試的時候忘了加這行結果手機直接爆炸!

測試之後可以發現第一次開啟的時候在主畫面載入這張圖時花了一些時間,但當我們關掉APP再次開啟時,載入圖片所花時間好像變快了,這就是快取的效果。

教學大概就到這裡了!小弟第一次寫請多多指教。

1 則留言: