使用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
下一篇文章,會針對這種加載圖片延遲的問題進行優化。