使用Android-Universal-Image-Loader加載網絡圖片

使用Android-Universal-Image-Loader加載網絡圖片

Android-Universal-Image-Loader是一個開源的Android圖片加載輔助組件,其主要目的是圖片加載,緩存,顯示。提供了一系列配置選項和圖片加載,緩存的控制。.

GitHub地址:https://github.com/nostra13/Android-Universal-Image-Loader

Android-Universal-Image-Loader的開源代碼裏本身是有示例代碼的,在這裏我們同樣寫一段代碼,在界面上有一個GridView.然後從網絡加載圖片到GridView。

關於頁面上下滑動,圖片加載的問題,可以實現一個AbsListView.OnScrollListener,在滑動的時候,觸發notifyDataSetChanged來更新整個GridView所有的Item的View。但是從高效的角度,應該只刷新對應的View即可,因爲新的Item滑出的時候,本來就是通過adapter的getView()返回應該刷新的那個Item的View,而對於其他已經存在的Item,是不需要在重新加載的。

Android-Universal-Image-Loader很好地解決圖片異步加載的問題。在getView()中再去通過ImageLoader.displayImage()來從網絡中獲取圖片也可以。它會把圖片獲取任務交給線程池去操作。在數據返回後,再將圖像賦給ImageView。

代碼用到了以下開源庫
Android-Universal-Image-Loader:請求,緩存,加載網絡圖片
jsoup:HTML解析庫

效果圖:
這裏寫圖片描述

源碼:

manifest 記得加權限

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

主界面LayOut

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <GridView
        android:id="@+id/gridView1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp"
        android:horizontalSpacing="4dp"
        android:verticalSpacing="4dp"
        android:stretchMode="columnWidth"
        android:numColumns="3" >
    </GridView>

</RelativeLayout>

Item的layout

<?xml version="1.0" encoding="utf-8"?>
<com.example.gridpic.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
<!-- 把圖片不按比例擴大/縮小到View的大小顯示 -->
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
         />

</com.example.gridpic.SquareLayout>

自定義的一個Layout

用來wrap每一個Item。爲了鎖定圖片爲正方形。

package com.example.gridpic;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
//參考http://blog.chengyunfeng.com/?p=465
//幫助鎖定GridView的Item的長寬。
public class SquareLayout extends RelativeLayout {
    public SquareLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public SquareLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SquareLayout(Context context) {
        super(context);
    }

    @SuppressWarnings("unused")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));

        // Children are just made to fill our space.
        int childWidthSize = getMeasuredWidth();
        int childHeightSize = getMeasuredHeight();
        //高度和寬度一樣
        heightMeasureSpec = widthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidthSize, MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    };
}

##自定義的BaseAdapter
通過ImageLoader加載每幅圖片,如果之前已經有本地緩存了,則從本地直接讀取
```java
package com.example.gridpic;

import java.util.List;

import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.BaseAdapter;
import android.widget.ImageView;


public class MyAdapter extends BaseAdapter {
    List<String> imageList;
    protected ImageLoader imageLoader = ImageLoader.getInstance();
    protected DisplayImageOptions options;
    private LayoutInflater mInflater;
    public MyAdapter(Context context,List<String> imageList) {
        super();
        this.imageList = imageList;
        options = new DisplayImageOptions.Builder()
        .showImageOnLoading(R.drawable.ic_launcher)
        .showImageForEmptyUri(R.drawable.ic_launcher)
        .showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
        .cacheOnDisk(true).bitmapConfig(Bitmap.Config.RGB_565).build();

        this.mInflater = LayoutInflater.from(context);
        //初始化ImageLoader
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(
                context);
        config.threadPriority(Thread.NORM_PRIORITY - 2);
        config.denyCacheImageMultipleSizesInMemory();
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
        config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
        config.tasksProcessingOrder(QueueProcessingType.LIFO);
        config.writeDebugLogs(); // Remove for release app
        ImageLoader.getInstance().init(config.build());
    }

    @Override
    public int getCount() {
        return imageList.size();
    }

    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;
        if (view == null) {
            view = mInflater.inflate(R.layout.picitem, null);
            holder = new ViewHolder();
            holder.image=(ImageView) view.findViewById(R.id.imageView1);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        imageLoader.displayImage(imageList.get(position),
                holder.image, options);
        Log.e("whatever", "Get View:"+position+". url="+imageList.get(position));
        return view;
    }

    final class ViewHolder{

        public ImageView image;

    }

}





<div class="se-preview-section-delimiter"></div>

主界面Activity

啓動後首先從網站獲取一個圖片URL地址的列表,並保存在List中,然後通過Handler發送給主線程,設定gridView的Adapter。

package com.example.gridpic;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;

import android.widget.GridView;

public class MainActivity extends Activity {
    List<String> imageList;
    GridView gridView;
    volatile Boolean urlReady = false;

    Handler myHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gridView = (GridView) findViewById(R.id.gridView1);
        new Thread(getImageRunnabe).start();// 準備圖片URL

        myHandler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                case 0xff:
                    Log.e("whatever", "URL ready");
                    MyAdapter mAdapter = new MyAdapter(getApplicationContext(),imageList);
                    gridView.setAdapter(mAdapter);
                    break;
                default:
                    break;
                }
                super.handleMessage(msg);
            }
        };

    }

    Runnable getImageRunnabe = new Runnable() {
        @Override
        public void run() {
            // TODO Auto-generated method stub
            imageList = getImageURL();
            MainActivity.this.myHandler.sendEmptyMessage(0xff);
        }
    };

    // 事先得到一大批圖像的URL地址保存在List中,作爲網絡圖片加載的數據源,如果本來手裏就有圖片的URL鏈接地址,可以省略此步驟
    public ArrayList<String> getImageURL() {

        // 4.0之後訪問網絡不能放在主線程中做
        ArrayList<String> imageList = new ArrayList<String>();
        String url = "http://www.juzimi.com/meitumeiju?page=";
        for (int i = 1; i < 10; i++) {
            String mUrl = url + String.valueOf(i);
            Log.e("whatever", mUrl);
            try {
                Document doc = Jsoup.connect(mUrl).get();
                Elements es1 = doc.getElementsByClass("chromeimg");
                for (Element e : es1) {
                    imageList.add(e.attr("src"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        urlReady = true;
        return imageList;

    }

}





<div class="se-preview-section-delimiter"></div>

最終效果就是:
向下滑動GridView. 新的Item會調用getView來獲取View。這時會把請求提交給ImageLoader。ImageLoader如果在本地找不到對應圖片。就回去網絡上下載。
於是可以看到效果中,圖片加載會需要一定時間的效果。

啓動應用->向下滑動 過程的log如下:

03-27 18:19:47.673: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=1
03-27 18:19:48.413: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=2
03-27 18:19:49.203: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=3
03-27 18:19:49.743: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=4
03-27 18:19:50.223: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=5
03-27 18:19:51.713: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=6
03-27 18:19:52.333: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=7
03-27 18:19:53.813: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=8
03-27 18:19:54.573: E/whatever(1802): http://www.juzimi.com/meitumeiju?page=9
03-27 18:19:55.643: E/whatever(1802): URL ready
03-27 18:19:55.703: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:55.703: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:55.703: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:55.713: E/whatever(1802): Get View:1. url=http://file.juzimi.com/weibopic/jazdmo2.jpg
03-27 18:19:55.713: E/whatever(1802): Get View:2. url=http://file.juzimi.com/weibopic/juzrmd4.jpg
03-27 18:19:55.713: E/whatever(1802): Get View:3. url=http://file.juzimi.com/weibopic/jozpmp6.jpg
03-27 18:19:55.723: E/whatever(1802): Get View:4. url=http://file.juzimi.com/weibopic/jlzamd1.jpg
03-27 18:19:55.723: E/whatever(1802): Get View:5. url=http://file.juzimi.com/weibopic/jezxmx2.jpg
03-27 18:19:55.723: E/whatever(1802): Get View:6. url=http://file.juzimi.com/weibopic/jozump.jpg
03-27 18:19:55.723: E/whatever(1802): Get View:7. url=http://file.juzimi.com/weibopic/jpzxml3.jpg
03-27 18:19:55.733: E/whatever(1802): Get View:8. url=http://file.juzimi.com/weibopic/jdzumu1.jpg
03-27 18:19:55.733: E/whatever(1802): Get View:9. url=http://file.juzimi.com/weibopic/jazxme.jpg
03-27 18:19:55.733: E/whatever(1802): Get View:10. url=http://file.juzimi.com/weibopic/jpzamr4.jpg
03-27 18:19:55.733: E/whatever(1802): Get View:11. url=http://file.juzimi.com/weibopic/jpzrmd1.jpg
03-27 18:19:55.743: E/whatever(1802): Get View:12. url=http://file.juzimi.com/weibopic/jxzima1.jpg
03-27 18:19:55.743: E/whatever(1802): Get View:13. url=http://file.juzimi.com/weibopic/jrzumx5.jpg
03-27 18:19:55.743: E/whatever(1802): Get View:14. url=http://file.juzimi.com/weibopic/jlzema6.jpg
03-27 18:19:58.243: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:58.253: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:58.543: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:58.543: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:59.413: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:19:59.413: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.003: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.003: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.313: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.313: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.443: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.453: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.983: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:00.983: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.043: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.043: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.183: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.183: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.613: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.613: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.643: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:01.643: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:02.533: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:02.533: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.113: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.113: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.363: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.363: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.793: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:03.793: E/whatever(1802): Get View:0. url=http://file.juzimi.com/weibopic/jozrmu4.jpg
03-27 18:20:09.113: E/whatever(1802): Get View:15. url=http://file.juzimi.com/weibopic/juzemx2.jpg
03-27 18:20:09.113: E/whatever(1802): Get View:16. url=http://file.juzimi.com/weibopic/jpzemo2.jpg
03-27 18:20:09.123: E/whatever(1802): Get View:17. url=http://file.juzimi.com/weibopic/jezrmd5.jpg
03-27 18:20:09.203: E/whatever(1802): Get View:18. url=http://file.juzimi.com/weibopic/jeziml4.jpg
03-27 18:20:09.203: E/whatever(1802): Get View:19. url=http://file.juzimi.com/weibopic/jdzimu4.jpg
03-27 18:20:09.203: E/whatever(1802): Get View:20. url=http://file.juzimi.com/weibopic/jezuml.jpg
03-27 18:20:09.313: E/whatever(1802): Get View:21. url=http://file.juzimi.com/weibopic/jlzrme1.jpg
03-27 18:20:09.313: E/whatever(1802): Get View:22. url=http://file.juzimi.com/weibopic/jozxml.jpg
03-27 18:20:09.313: E/whatever(1802): Get View:23. url=http://file.juzimi.com/weibopic/jozamr.jpg

下一篇文章,會針對這種加載圖片延遲的問題進行優化。

發佈了88 篇原創文章 · 獲贊 5 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章