Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Volley分析(二)——實現

Android Volley分析(二)——實現

編輯:關於Android編程

在Android Volley分析(一)——結構中主要分析了Volley的基本組件和框架結構,組件主要是定義的接口,也就是說我們可以實現這些接口來定制自己的Volley版本,比如NetWork、Cache、Request等等。Android Volley在com.android.volley.toolbox下已經做了這些工作,下面就看看這些具體的實現內容

\

先看一個Volley使用的例子<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">final TextView mTextView = (TextView) findViewById(R.id.text); ... // Instantiate the RequestQueue. RequestQueue queue = Volley.newRequestQueue(this); String url ="http://www.google.com"; // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(String response) { // Display the first 500 characters of the response string. mTextView.setText("Response is: "+ response.substring(0,500)); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mTextView.setText("That didn't work!"); } }); // Add the request to the RequestQueue. queue.add(stringRequest);
這是官方volley教程的一個例子,使用Volley的步驟

1、Volley.newRequestQueue();

2、new Request();

3、queue.add(request);

在newRequestQueue的時候會初始化基本的組件

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

        String userAgent = "volley/0";
        try {
            String packageName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
            userAgent = packageName + "/" + info.versionCode;
        } catch (NameNotFoundException e) {
        }

        if (stack == null) {
            if (Build.VERSION.SDK_INT >= 9) {
                stack = new HurlStack();
            } else {
                // Prior to Gingerbread, HttpUrlConnection was unreliable.
                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
            }
        }

        Network network = new BasicNetwork(stack);

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
        queue.start();

        return queue;
    }

1、BasicNetwork

BasicNetwork是對Network接口的實現,同時還將聯網操作部分提取出來形成HttpStack,原因是Android 2.3之前網絡操作推薦使用HttpClient,2.3之後Android做了優化推薦使用HttpUrlConnection。

2、DiskBasedCache

DiskBasedCache是對Cache對實現,用於硬盤緩存,也就是將數據保存為特定的文件。

結合LruCache試著總結一下緩存的一般方法:

映射結構——LinkedHashMap,內部實現了Lru的算法排序,可以直接使用

put——存儲,容量計數增加,判斷是否超出最大容量,超出則刪除最少使用的

get——key到entry的映射

remove——刪除,容量計數減小

3、ImageLoader

ImageLoader是一個圖片加載類,封裝了請求,提供了內存緩存機制,批處理等,讓圖片加載更容易使用,下面看一下它的用法:

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
            private final LruCache
                    cache = new LruCache(20);

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

            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
         R.drawable.def_image, R.drawable.err_image));

(示例來源 Making a Standard Request )

內存緩存推薦使用LruCache,需要實現ImageLoader.ImageCache接口。圖片的加載通過imageLoader.get()方法實現,

    public ImageContainer get(String requestUrl, ImageListener imageListener,
            int maxWidth, int maxHeight) {
        // only fulfill requests that were initiated from the main thread.
        throwIfNotOnMainThread();

        final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);

        // Try to look up the request in the cache of remote images.
        Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
        if (cachedBitmap != null) {
            // Return the cached bitmap.
            ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null);
            imageListener.onResponse(container, true);
            return container;
        }

        // The bitmap did not exist in the cache, fetch it!
        ImageContainer imageContainer =
                new ImageContainer(null, requestUrl, cacheKey, imageListener);

        // Update the caller to let them know that they should use the default bitmap.
        imageListener.onResponse(imageContainer, true);

        // Check to see if a request is already in-flight.
        BatchedImageRequest request = mInFlightRequests.get(cacheKey);
        if (request != null) {
            // If it is, add this request to the list of listeners.
            request.addContainer(imageContainer);
            return imageContainer;
        }

        // The request is not already in flight. Send the new request to the network and
        // track it.
        Request newRequest =
            new ImageRequest(requestUrl, new Listener() {
                @Override
                public void onResponse(Bitmap response) {
                    onGetImageSuccess(cacheKey, response);
                }
            }, maxWidth, maxHeight,
            Config.RGB_565, new ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    onGetImageError(cacheKey, error);
                }
            });

        mRequestQueue.add(newRequest);
        mInFlightRequests.put(cacheKey,
                new BatchedImageRequest(newRequest, imageContainer));
        return imageContainer;
    }

首先得到一個cacheKey,這個是統一的規則

    private static String getCacheKey(String url, int maxWidth, int maxHeight) {
        return new StringBuilder(url.length() + 12).append("#W").append(maxWidth)
                .append("#H").append(maxHeight).append(url).toString();
    }

然後在緩存cache中查找,沒找到就講請求添加到批處理任務BitmapImageRequest中,這裡有兩個類,ImageContainer和BitmapImageRequest:

ImageContainer是一個包裝類,裡面包含了bitmap、url、cacheKey和listener,當得到bitmap後會通過listener將bitmap返回;

BitmapImageRequest是將相同url請求放在一起,這樣就可以只向網絡請求一次,返回結果後再分別設置到目標上,從而達到減少網絡請求對目的。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved