使用Android-Universal-Image-Loader加载网络图片
使用Android-Universal-Image-Loader加载网络图片
Android-Universal-Image-Loader是一个开源的Android图片加载辅助组件,其主要目的是图片加载,缓存,显示。提供了一系列配置选项和图片加载,缓存的控制。
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
下一篇文章,会针对这种加载图片延迟的问题进行优化。
————————————————