近几天实现加载网络图片,中途遇到好多bug,其中最令人头疼的便是OOM超内存的bug,现在还是没能解决。可能的原因就是加载的网络图片超出手机内存。
这只能改变图片自身的大小,或者使用缩略图处理的方式了 。不过缩略图我还没有了解,希望大神看到后可以指点一二。
下面就是listView中加载网络图片等信息的部分核心源码。
myBaseAdapter.java文件
package com.iyoutingche.android.bean;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.iyoutingche.android.image.ImageLoad;
import com.zhy.weixin6.ui.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class myBaseAdapter extends BaseAdapter implements AbsListView.OnScrollListener {
private LayoutInflater mInflater;
private ImageLoad mImageLoad;
private int mStart,mEnd;
public static String[] URLS; //保存所有url地址
boolean mFirst;
private List<HashMap<String, String>> data = new ArrayList<HashMap<String,String>>();
private String url = null;// 存放图片的URL地址
//data:从网络获的数据
//resource:布局文件的id
//from:map中的view值
//to:布局文件中的id
public myBaseAdapter(Context context, List<HashMap<String, String>> data,ListView listview) {
mInflater = LayoutInflater.from(context);
this.data = data;
mFirst = true;
mImageLoad=new ImageLoad(listview); //保证创建一个ImageLoad对象
URLS = new String[data.size()];
Log.i("urlsize-----", data.size()+"");
listview.setOnScrollListener(this);
for(int i=0;i<data.size();i++){
URLS[i] = data.get(i).get("img").toString();
}
}
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressLint("ViewHolder")
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHodler hodler = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
hodler = new ViewHodler();
hodler.pcar_name = (TextView) convertView
.findViewById(R.id.item_name);
hodler.pcar_number = (TextView) convertView
.findViewById(R.id.item_number);
hodler.pcar_from = (TextView) convertView
.findViewById(R.id.item_from);
hodler.depot_count = (TextView)convertView
.findViewById(R.id.item_depotCount);
hodler.pcar_img = (ImageView) convertView.findViewById(R.id.item_img);
convertView.setTag(hodler); //将convertView与ViewHold创建联系
}else{
hodler = (ViewHodler) convertView.getTag(); //如果convertView不为空,直接得到viewHold的信息就行了。
}
hodler.pcar_name.setText(data.get(position).get("name").toString());
hodler.pcar_number.setText("剩"+data.get(position).get("number").toString());
hodler.pcar_from.setText("地址:"+data.get(position).get("from").toString());
hodler.depot_count.setText("共"+data.get(position).get("depot_count").toString());
//异步加载图片
url = data.get(position).get("img").toString();
mImageLoad.showImageByAsyncTask(hodler.pcar_img, url);
hodler.pcar_img.setTag(url);
// new ImageLoad().showImageByThread(hodler.pcar_img, url);
return convertView;
}
class ViewHodler {
TextView pcar_name;// 停车场名称
TextView pcar_number;// 剩余空车位
TextView pcar_from;// 停车场位置
ImageView pcar_img;// 停车场的图片
TextView depot_count; //停车场总车位
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(mEnd >data.size()){
Log.i("--------越界了吗?", mEnd+"");
mImageLoad.cancelAllTasks();
return;
}
if(scrollState == SCROLL_STATE_IDLE){ //如果是停止状态
//加载所有项
Log.i("值", "开始"+mStart+",结束"+mEnd);
mImageLoad.loadImages(mStart, mEnd);
}else{
//停止加载
mImageLoad.cancelAllTasks();
}
}
//每次都会调用该方法
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
mStart = firstVisibleItem;
mEnd = firstVisibleItem + visibleItemCount;
Log.i("索引-----", "开始"+mStart+",结束"+mEnd);
//第一次显示时,调用。
if(mFirst && visibleItemCount >0){
mImageLoad.loadImages(mStart, mEnd);
mFirst = false;
}
}
}
ImageLode.java文件
package com.iyoutingche.android.image;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import com.iyoutingche.android.bean.myBaseAdapter;
import com.zhy.weixin6.ui.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;
import android.widget.ListView;
public class ImageLoad {
//创建cache
private LruCache<String, Bitmap> mCaches;
private ListView mListView;
private Set<PcarAsyncTask> mTask;
public ImageLoad(ListView listview) {
mListView = listview;
mTask = new HashSet<PcarAsyncTask>();
//获取最大缓存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 4;
mCaches = new LruCache<String, Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap value) {
//每次存入缓存时调用
return value.getByteCount();
}
};
}
//增加到缓存
public void addBitmapToCache(String url,Bitmap bitmap) {
if(getBitmapFromCache(url) == null){ //校验当前缓存是否存在
mCaches.put(url, bitmap);
}
}
//获取缓存
public Bitmap getBitmapFromCache(String url){ //将Lru理解成map集合,用get方法获得key对应的value。
return mCaches.get(url);
}
// //通过Handler 将传递bitmap图片 为主线程更新UI
// private Handler mHandler = new Handler(){
// public void handleMessage(android.os.Message msg) {
// if(mImageView.getTag().equals(mUrl)){
// mImageView.setImageBitmap((Bitmap) msg.obj);
// }
// };
// };
public Bitmap bitmapFromUrl(String urlString){
Bitmap bitmap;
InputStream is = null;
try {
URL url = new URL(urlString); //将string类型的url转换成URL类型
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//通过inputStream对象 解析成bitmap
is = new BufferedInputStream(connection.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
//释放connection连接
connection.disconnect();
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
//采用AsyncTask 方法加载图片
public void showImageByAsyncTask(ImageView imageView , String url){
//从缓存中获取图片
Bitmap bitmap = getBitmapFromCache(url);
//缓存中不存在,就重新加载
if(bitmap == null){
// new PcarAsyncTask(url).execute(url);
imageView.setImageResource(R.drawable.actionbar_add_icon); //未加载图片前,默认加载本地的图片
Log.i("-------初次", "初次加载");
}else{
imageView.setImageBitmap(bitmap);
Log.i("-------以后加载", "再次加载");
}
}
private class PcarAsyncTask extends AsyncTask<String,Void, Bitmap>{
private String mUrl;
// private ImageView mImageView;
//建立构造方法,初始化imageview
public PcarAsyncTask(String url) {
mUrl = url;
}
//实现异步加载图片
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];
//从网络上获取图片
Bitmap bitmap = bitmapFromUrl(url);
if(bitmap != null){
//将不再缓存的图片加入缓存
addBitmapToCache(url, bitmap);
}
return bitmap;
}
//在imageView中设置bitmap参数
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);
if(imageView != null && bitmap != null){
imageView.setImageBitmap(bitmap);
}
mTask.remove(this);
}
}
//从网络中加载从start到end到缓存中
public void loadImages(int start ,int end){
for(int i = start ; i<=end ;i++ ){
String url = myBaseAdapter.URLS[i];
//从缓存中获取图片
Bitmap bitmap = getBitmapFromCache(url);
//缓存中不存在,就重新加载
if(bitmap == null){
PcarAsyncTask task = new PcarAsyncTask(url);
// new PcarAsyncTask(url).execute(url);
task.execute(url);
mTask.add(task);
}else{
ImageView imageView = (ImageView) mListView.findViewWithTag(url);
imageView.setImageBitmap(bitmap);
}
}
}
//取消所有任务
public void cancelAllTasks() {
if(mTask != null){
for (PcarAsyncTask task : mTask) {
task.cancel(false);
}
}
}
//
// //使用多线程进行一步加载
// public void showImageByThread(ImageView imageview , final String url) {
// mImageView = imageview;
// mUrl = url;
// new Thread(){
// public void run() {
// super.run();
// Bitmap bitmap = bitmapFromUrl(url);
// Message message = Message.obtain(); //重复利用message发送信息,节约资源。
// message.obj = bitmap;
// mHandler.sendMessage(message); //发送message
// };
// }.start();
// }
// public Bitmap bitmapFromUrl(String urlString){
// Bitmap bitmap;
// InputStream is = null;
// try {
// URL url = new URL(urlString); //将string类型的url转换成URL类型
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// //通过inputStream对象 解析成bitmap
// is = new BufferedInputStream(connection.getInputStream());
// bitmap = BitmapFactory.decodeStream(is);
// //释放connection连接
// connection.disconnect();
// return bitmap;
// } catch (IOException e) {
// e.printStackTrace();
// }finally{
// try {
// is.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// return null;
// }
}