編輯:關於Android編程
搜芽的移動開發這幾天進度相對來說非常的快。但是美中不足的就是網絡圖片的加載問題。我有兩套方案:
1)沿用迅雷動漫的圖片加載。迅雷動漫也是用的一個開源的庫。但是不知道是我使用出了問題還是真的是它的問題。在我迅速的下拉和回倒的時候,
不確定的會出現崩潰。logcat顯示loadImage裡面出現了內存溢出.out of memory.。這個我想應該不是我的問題。
2)采用外包的AsyncImageLoader。這個文件我沒有仔細看。然後實驗結果是,加載圖片巨慢。而且容易導致卡頓。
所以,我將希望轉向了universal-image-loader和volley。
聽說volley還封裝了異步http。而且是google公司的,所以,我選擇了volley
一篇值得贊賞的文章是:http://blog.csdn.net/sun1021976312/article/details/24672707
說真的。本文的理論部分,也是轉自它。我們在後面進行封裝,然後使用然後展示效果。
Volley是將AsyncHttpClient和Universal-Image-Loader的優點集成於一身的一個框架。我們都知道,Universal-Image-Loader具備非常強大的加載網絡圖片的功能,而使用Volley,我們也可以實現基本類似的效果,並且在性能上也豪不遜色於Universal-Image-Loader,下面我們就來具體學習一下吧。
前面我們已經學習過了StringRequest和JsonRequest的用法,並且總結出了它們的用法都是非常類似的,基本就是進行以下三步操作即可:
1. 創建一個RequestQueue對象。
2. 創建一個Request對象。
3. 將Request對象添加到RequestQueue裡面。
其中,StringRequest和JsonRequest都是繼承自Request的,所以它們的用法才會如此類似。那麼不用多說,今天我們要學習的ImageRequest,相信你從名字上就已經猜出來了,它也是繼承自Request的,因此它的用法也是基本相同的,首先需要獲取到一個RequestQueue對象,可以調用如下方法獲取到:
[java] view plaincopy
最後將這個ImageRequest對象添加到RequestQueue裡就可以了,如下所示:
[java] view plaincopy
如果你覺得ImageRequest已經非常好用了,那我只能說你太容易滿足了 ^_^。實際上,Volley在請求網絡圖片方面可以做到的還遠遠不止這些,而ImageLoader就是一個很好的例子。ImageLoader也可以用於加載網絡上的圖片,並且它的內部也是使用ImageRequest來實現的,不過ImageLoader明顯要比ImageRequest更加高效,因為它不僅可以幫我們對圖片進行緩存,還可以過濾掉重復的鏈接,避免重復發送請求。
由於ImageLoader已經不是繼承自Request的了,所以它的用法也和我們之前學到的內容有所不同,總結起來大致可以分為以下四步:
1. 創建一個RequestQueue對象。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CjIuILS0vajSu7j2SW1hZ2VMb2FkZXK21M/zoaM8L3A+CjxwPgozLiC78cih0ru49kltYWdlTGlzdGVuZXK21M/zoaM8L3A+CjxwPgo0LiC199PDSW1hZ2VMb2FkZXK1xGdldCgpt723qLzT1NjN+MLnyc+1xM28xqyhozwvcD4KPHA+Cs/Cw+bO0sPHvs3AtLC01dXV4rj2sr3W6KOs0afPsNK7z8JJbWFnZUxvYWRlcrXE08O3qLDJoaPK18/ItdrSu7K9tcS0tL2oUmVxdWVzdFF1ZXVlttTP887Sw8fS0b6t0LS5/brctuCx6cHLo6zP4NDF0tG+rbK708PU2dbYuLS96cncwcujrMTHw7S+zbTTtdq2/rK9v6rKvNGnz7CwyaOs0MK9qNK7uPZJbWFnZUxvYWRlcrbUz/OjrLT6wuvI58/Cy/nKvqO6PC9wPgoKCgo8c3Ryb25nPltqYXZhXTwvc3Ryb25nPiB2aWV3CiBwbGFpbmNvcHk8aW1nIHNyYz0="https://www.android5.online/Android/UploadFiles_5356/201702/2017022316263379.png" width="12" height="12" alt="在CODE上查看代碼片">
接下來需要獲取一個ImageListener對象,代碼如下所示:
[java] view plaincopy
最後,調用ImageLoader的get()方法來加載圖片,代碼如下所示:
[java] view plaincopyget()方法接收兩個參數,第一個參數就是圖片的URL地址,第二個參數則是剛剛獲取到的ImageListener對象。當然,如果你想對圖片的大小進行限制,也可以使用get()方法的重載,指定圖片允許的最大寬度和高度,如下所示:
[java] view plaincopy
現在運行一下程序並開始加載圖片,你將看到ImageView中會先顯示一張默認的圖片,等到網絡上的圖片加載完成後,ImageView則會自動顯示該圖,效果如下圖所示。
雖然現在我們已經掌握了ImageLoader的用法,但是剛才介紹的ImageLoader的優點卻還沒有使用到。為什麼呢?因為這裡創建的ImageCache對象是一個空的實現,完全沒能起到圖片緩存的作用。其實寫一個ImageCache也非常簡單,但是如果想要寫一個性能非常好的ImageCache,最好就要借助Android提供的LruCache功能了,如果你對LruCache還不了解,可以參考我之前的一篇博客Android高效加載大圖、多圖解決方案,有效避免程序OOM。
這裡我們新建一個BitmapCache並實現了ImageCache接口,如下所示:
[java] view plaincopy
除了以上兩種方式之外,Volley還提供了第三種方式來加載網絡圖片,即使用NetworkImageView。不同於以上兩種方式,NetworkImageView是一個自定義控制,它是繼承自ImageView的,具備ImageView控件的所有功能,並且在原生的基礎之上加入了加載網絡圖片的功能。NetworkImageView控件的用法要比前兩種方式更加簡單,大致可以分為以下五步:
1. 創建一個RequestQueue對象。
2. 創建一個ImageLoader對象。
3. 在布局文件中添加一個NetworkImageView控件。4. 在代碼中獲取該控件的實例。
5. 設置要加載的圖片地址。
其中,第一第二步和ImageLoader的用法是完全一樣的,因此這裡我們就從第三步開始學習了。首先修改布局文件中的代碼,在裡面加入NetworkImageView控件,如下所示:
[html] view plaincopy
好了,就是這麼簡單,現在重新運行一下程序,你將看到和使用ImageLoader來加載圖片一模一樣的效果,這裡我就不再截圖了。
這時有的朋友可能就會問了,使用ImageRequest和ImageLoader這兩種方式來加載網絡圖片,都可以傳入一個最大寬度和高度的參數來對圖片進行壓縮,而NetworkImageView中則完全沒有提供設置最大寬度和高度的方法,那麼是不是使用NetworkImageView來加載的圖片都不會進行壓縮呢?
其實並不是這樣的,NetworkImageView並不需要提供任何設置最大寬高的方法也能夠對加載的圖片進行壓縮。這是由於NetworkImageView是一個控件,在加載圖片的時候它會自動獲取自身的寬高,然後對比網絡圖片的寬度,再決定是否需要對圖片進行壓縮。也就是說,壓縮過程是在內部完全自動化的,並不需要我們關心,NetworkImageView會始終呈現給我們一張大小剛剛好的網絡圖片,不會多占用任何一點內存,這也是NetworkImageView最簡單好用的一點吧。
當然了,如果你不想對圖片進行壓縮的話,其實也很簡單,只需要在布局文件中把NetworkImageView的layout_width和layout_height都設置成wrap_content就可以了,這樣NetworkImageView就會將該圖片的原始大小展示出來,不會進行任何壓縮。
首先我們要有布局用到NetworkImageView
然後由於NetworkImageView需要ImageLoader。所以我們封裝了一下它對Volley的依賴。
package com.souya.seller.util.ex; import android.content.Context; import android.graphics.Bitmap; import android.support.v4.util.LruCache; import com.android.volley.RequestQueue; import com.android.volley.toolbox.ImageLoader; import com.android.volley.toolbox.ImageLoader.ImageCache; import com.android.volley.toolbox.Volley; import com.souya.seller.app.SellerApplication; public class VolleyImage { private static final String TAG = "Volley"; private static RequestQueue mReuestQueue; private static ImageLoader mImageLoader; private static Context mContext; private static BitmapCache mBitmapCache; static { mContext = SellerApplication.getInstance(); mReuestQueue = Volley.newRequestQueue(mContext); mBitmapCache = BitmapCache.getInstance(); mImageLoader = new ImageLoader(mReuestQueue, mBitmapCache); } // private static VolleyImage mInstance = null; public VolleyImage() { } // public static VolleyImage getInstance(){ // return new VolleyImage(); // } public static ImageLoader getImageLoader(){ return mImageLoader; } } class BitmapCache implements ImageCache { private LruCachemCache; public BitmapCache() { int maxSize = 50 * 1024 * 1024; mCache = new LruCache (maxSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getRowBytes() * bitmap.getHeight(); } }; } public static BitmapCache getInstance() { return new BitmapCache(); } @Override public Bitmap getBitmap(String url) { return mCache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { mCache.put(url, bitmap); } }
holder.mPoster = (NetworkImageView) convertView.findViewById(R.id.poster);
public void populateViews(MCloth cloth, ImageFetcher fetcher) { mLabel.setVisibility(View.VISIBLE); mLabel.setText(cloth.title); mCenterView.setVisibility(View.INVISIBLE); if (!TextUtils.isEmpty(cloth.imgUrl)) { //fetcher.loadImage(SOUYA_SERVER_URL + cloth.imgUrl, mPoster); mPoster.setImageUrl(WEBInterface.GetFullUrl(cloth.imgUrl), VolleyImage.getImageLoader()); } }
非常的流暢,沒有卡頓。加載速度很快。
貼圖
最近用淘寶客戶端的時候,編輯地址的時候有個地區選擇的功能。看上面的效果覺得挺酷,滾動的時候,是最後一個從下面飛上來挨著前一個。就自己鼓搗一個出來玩玩。說了效果可能不太直觀
本文主要和大家分享如何在Android應用開發過程中如何進行單元測試,個人在做項目的過程中,覺得單元測試很有必要,以保證我們編寫程序的正確性。下面我們先大概了解下單元測試
底部菜單欄很重要,我看了一下很多應用軟件都是用了底部菜單欄,這裡使用了tabhost做了一種通用的(就是可以像微信那樣顯示未讀消息數量的,雖然之前也做過但是layout下
OS體系結構介紹:第一、操作系統層(OS)第二、各種庫(Libraries)和Android 運行環境(RunTime)第三、應用程序框架(Application Fra