Volley的簡單封裝


  算了一下,好像有很久沒有寫博客了。其實,關於寫博客這件事,我從來沒有把他當成我的一種任務,而是在學習過程中的一種總結和自我發現,同樣也是為了練一練文筆,說不定有一天,我也能出一本書像《第一行代碼》,《安卓從小工到專家》,《App研發錄》等等這樣的書。人生短短數十載,總要留下些什么。好像說的有點多,話不多說。來談談今天的主要內容。我總在一些交流群中看到有人說,那個XXX二次封裝的OkHttp如何怎樣怎樣。其實,當我看到他這樣說的時候我在想,為什么不自己進行二次封裝同樣更加滿足自己的需求呢?也許你會覺得這東西很難,人家有現成的東西為什么不用呢?我覺得,前提是你要理解了才能拿來用。話不多說,拿一個我自己做的Demo給大家看一看。

這個小東西,我所使用的是Volley,並且實現了對Volley的簡單二次封裝。這里寫出來,希望對你有所啟發。

  數據方面,由於調用的是聚合上的免費API,返回的數據是Json。在安卓中處理Json,其實首選是想Gson,fastJson,這樣的框架。因為我Gson用的比較多,並且關於寫JavaBean對象,Android Studio 也有jsonformat這樣的小插件可以快速實現,省去了很多時間。

***Volley整合Gson**

  好在Volley提供了一個Request類幫助我們實現自定義的Request。所以實現起來並不復雜。我們希望,從我們自定義的Requet中能夠直接返回我們的JavaBean對象,便於我們對數據的操作。實現代碼:

 

public class ApiJsonRequest<T>extends Request<T>{
    private Class<T> clazz;
    private Response.Listener<T> mListener;
    private Gson gson;
    private int position;

    public ApiJsonRequest(int method, String url, Response.ErrorListener errorListener,
                          Response.Listener<T> listener, Class<T> clazz) {
        super(method, url, errorListener);
        this.mListener=listener;
        this.clazz=clazz;
    }

    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        String json;
        try {
            json=new String(response.data, HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            json=new String(response.data);
        }
        T obj;
        try {
            if (gson==null) {
                gson = new Gson();
            }
            obj=gson.fromJson(json,clazz);
            return Response.success(obj,HttpHeaderParser.parseCacheHeaders(response));
        }catch (Exception e) {
            return Response.error(new ParseError());
        }

    }

    @Override
    protected void deliverResponse(T response) {
        mListener.onResponse(response);
    }
}

  可以看到,這里主要有三個方法需要我們去實現。構造方法中,我們傳入一個請求成功的監聽。由於我們需要返回JavaBean對象,但是卻不知道這個JavaBean對象具體指向誰,所以這里可以傳入一個泛型T,在實現這個Request的時候就指定JavaBean對象用於Gson解析。之后再parseNetworkResponse中通過NetworkResponse拿到調用String類的構造方法,將二進制字節組轉換為一個Java字符串,用於我們的Gson解析,為了防止Gson對象在數據請求的時候被重復調用,要在初始化時進行判空。最后調用Json.fromJson將這個對象Response出去;deliverResponse這個方法主要用於決定我們返回的數據對象。下面是使用:

 

private void getData() {
        ApiJsonRequest<NewsParseBean> apiJsonRequest = new ApiJsonRequest<>(Request.Method.GET,
                NewsBean.requestUrl + type + NewsBean.apiKey, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {


            }
        }, new Response.Listener<NewsParseBean>() {
            @Override
            public void onResponse(NewsParseBean response) {
                //獲取最新數據
                processData(response);
                //顯示新聞
                showNews();

            }
        }, NewsParseBean.class,position);
        apiJsonRequest.setTag(getClass().getSimpleName());
        requestQueue.add(apiJsonRequest);
    }

 

一個簡單的整合Gson的Volley就寫完了。是不是很簡單?

***整合LruCache***

  上圖那個小Demo,運行起來是十分的流暢。在圖片加載方面,我所使用的是Android中的LruCache。一種內存緩存策略,你能看到,其實加載速度是非常的快,非常的流暢的。附上代碼:

public class ApiImageCache implements ImageLoader.ImageCache {
    private LruCache<String,Bitmap>lruCache;
    private static int maxSize= ApiConstant.IMAGE_SIZE;
    private static ApiImageCache instance;
    private ApiImageCache() {
        lruCache=new LruCache<String, Bitmap>(maxSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount()/1024/1024;
            }
        };
    }
    public static synchronized ApiImageCache getInstance () {
        if (instance==null) {
            instance=new ApiImageCache(){};
        }
        return instance;
    }
    @Override
    public Bitmap getBitmap(String url) {
        return lruCache.get(url);
    }

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

    }
}

在實現Volley加載圖片的時候需要我們對圖片進行自定義的處理,這里實現ImageLoader.ImageCache就可以了。之后,我為了方便,將它寫成單例。在構造方法中使用LruCache進行圖片加載處理。實現很簡單,需要注意的是LruCache返回的是圖片的大小。

Volley:

public class ApiVolleyUtils {
    private static ApiVolleyUtils instance;
    private static RequestQueue requestQueue;
    private static ImageLoader imageLoader;
    private static ImageLoader.ImageCache imageCache;

    public RequestQueue getRequestQueue() {
        return requestQueue;
    }

    public ImageLoader getImageLoader() {
        return imageLoader;
    }

    public ImageLoader.ImageCache getImageCache() {
        return imageCache;
    }

    private ApiVolleyUtils(Context context){
        requestQueue= Volley.newRequestQueue(context);
        imageCache=ApiImageCache.getInstance();
        imageLoader=new ImageLoader(requestQueue,imageCache);

    }
    public static ApiVolleyUtils getInstance(Context context) {
        if (instance==null) {
            synchronized (ApiVolleyUtils.class){
                if (instance==null) {
                    instance=new ApiVolleyUtils(context);
                }
            }
        }
        return instance;
    }

}

使用:

ImageLoader imageLoader = apiVolleyUtils.getImageLoader();
            if (!NetUtils.isNetWork(UIUtils.getContext())) {
                // getDiskImage(holder, diskLruCache, key);
            } else {
                //getNetDisk(position, diskLruCache, key);
                imageLoader.get(respondList.get(position).getThumbnail_pic_s(),
                        new ImageLoader.ImageListener() {
                            @Override
                            public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
                                holder.ivNews.setImageBitmap(response.getBitmap());
                            }
                            @Override
                            public void onErrorResponse(VolleyError error) {

                            }
                        });

好了,關於這個小Demo中的Volley網絡模塊接介紹完了,關於這些框架,我們不僅需要學習如何使用跟重要的是,要學會如何對框架進行二次封裝,滿足自己的實際需要。希望這篇博客對你有所啟發。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM