使用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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章