关于listview加载数据卡顿的,求解决方案

Canra 2015-11-18 02:06:36
如题,ListView加载数据卡顿问题,下面先上一张locat图
应该是内存没有释放的问题吧,下面贴Imageloader代码:
**
* 对图片进行管理的工具类。
*
*/
public class ImageLoader {

/**
* 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。
*/
private static LruCache<String, Bitmap> mMemoryCache;

/**
* ImageLoader的实例。
*/
private static ImageLoader mImageLoader;

private ImageLoader() {
// 获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
// 设置图片缓存大小为程序最大可用内存的1/8
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// andorid2.3中没有getByteCount方法,改为如下
return bitmap.getRowBytes()*bitmap.getHeight();
}
};
}

/**
* 获取ImageLoader的实例。
*
* @return ImageLoader的实例。
*/
public static ImageLoader getInstance() {
if (mImageLoader == null) {
mImageLoader = new ImageLoader();
}
return mImageLoader;
}

/**
* 将一张图片存储到LruCache中。
*
* @param key
* LruCache的键,这里传入图片的URL地址。
* @param bitmap
* LruCache的键,这里传入从网络上下载的Bitmap对象。
*/
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemoryCache(key) == null) {
if(bitmap != null){
mMemoryCache.put(key, bitmap);
}
}
}

/**
* 从LruCache中获取一张图片,如果不存在就返回null。
*
* @param key
* LruCache的键,这里传入图片的URL地址。
* @return 对应传入键的Bitmap对象,或者null。
*/
public Bitmap getBitmapFromMemoryCache(String key) {
return mMemoryCache.get(key);
}

public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth) {
// 源图片的宽度
final int width = options.outWidth;
int inSampleSize = 1;
if (width > reqWidth) {
// 计算出实际宽度和目标宽度的比率
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = widthRatio;
}
return inSampleSize;
}

public static Bitmap decodeSampledBitmapFromResource(String pathName,
int reqWidth) {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth);
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(pathName, options);
}

}
下面贴MainActivity里面图片的相关代码:
//TODO 图片处理问题
/**
* 异步下载图片的任务。
*
* @author guolin
*/
class LoadImageTask extends AsyncTask<String, Void, Bitmap> {

/**
* 图片的URL地址
*/
private String mImageUrl;

/**
* 可重复使用的ImageView
*/
private ImageView mImageView;

public LoadImageTask() {

}

/**
* 将可重复使用的ImageView传入
*
* @param imageView
*/
public LoadImageTask(ImageView imageView) {
mImageView = imageView;
}

@Override
protected Bitmap doInBackground(String... params) {
mImageUrl = params[0];
Bitmap imageBitmap = imageLoader
.getBitmapFromMemoryCache(mImageUrl);
if (imageBitmap == null) {
imageBitmap = loadImage(mImageUrl);
}
return imageBitmap;
}

@Override
protected void onPostExecute(Bitmap bitmap) {

if (bitmap != null) {
double ratio = bitmap.getWidth() / (dm.heightPixels / 8 * 1.0);
int scaledHeight = (int) (bitmap.getHeight() / ratio);
addImage(mImageUrl,bitmap, dm.heightPixels / 8, scaledHeight);
}
taskCollection.remove(this);
}

/**
* 根据传入的URL,对图片进行加载。如果这张图片已经存在于SD卡中,则直接从SD卡里读取,否则就从网络上下载。
*
* @param imageUrl
* 图片的URL地址
* @return 加载到内存的图片。
*/
private Bitmap loadImage(String imageUrl) {

File imageFile = new File(getImagePath(imageUrl));
if (!imageFile.exists()) {
System.out.println("222222 "+imageUrl);
downloadImage(imageUrl);
}
Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(
imageFile.getPath(), dm.heightPixels / 8);
imageLoader.addBitmapToMemoryCache(imageUrl, bitmap);
return bitmap;
}

/**
* 向ImageView中添加一张图片
*
* @param bitmap
* 待添加的图片
* @param imageWidth
* 图片的宽度
* @param imageHeight
* 图片的高度
*/
private void addImage(String mImageUrl,Bitmap bitmap, int imageWidth, int imageHeight) {
if(shoppingCartProds.size() > 0 && mImageUrl != null && bitmap != null){
for(int i = 0;i<shoppingCartProds.size();i++){
if(shoppingCartProds.get(i).getMainUrl() != null){
if(shoppingCartProds.get(i).getMainUrl().equals(mImageUrl)){
shoppingCartProds.get(i).setBmp(bitmap);
storeAdapter.notifyDataSetChanged();
break;
}
}
}
}
}

/**
* 将图片下载到SD卡缓存起来。
*
* @param imageUrl
* 图片的URL地址。
*/
private void downloadImage(String imageUrl) {
HttpURLConnection con = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
File imageFile = null;
try {

URL url = new URL(imageUrl);
con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5 * 1000);
con.setReadTimeout(15 * 1000);
con.setDoInput(true);
con.setDoOutput(true);
bis = new BufferedInputStream(con.getInputStream());
imageFile = new File(getImagePath(imageUrl));
fos = new FileOutputStream(imageFile);
bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int length;
while ((length = bis.read(b)) != -1) {
bos.write(b, 0, length);
bos.flush();
}

} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
if (con != null) {
con.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (imageFile != null) {

//TODO 获取图片保存路径
System.out.println("图片保存路径2 "+imageFile.getPath());

Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource(
imageFile.getPath(), dm.heightPixels / 8);
imageLoader.addBitmapToMemoryCache(imageUrl, bitmap);
}
}

/**
* 获取图片的本地存储路径。
*
* @param imageUrl
* 图片的URL地址。
* @return 图片的本地存储路径。
*/
private String getImagePath(String imageUrl) {
int lastSlashIndex = imageUrl.lastIndexOf("/");
String imageName = imageUrl.substring(lastSlashIndex + 1);
String imageDir = Environment.getExternalStorageDirectory()
.getPath() + GlobalVariable.localBmpPath;
File file = new File(imageDir);
if (!file.exists()) {
file.mkdirs();
}
String imagePath = imageDir + imageName;
System.out.println("图片路径 "+imagePath);
return imagePath;
}
}

求解,如果需要回收,应该怎么处理,现在每次进到这个也页面都是卡顿的,而且图片都没有全部加载出来,这个项目外包回来的
...全文
872 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
Canra 2015-11-23
  • 打赏
  • 举报
回复
引用 10 楼 jeabo 的回复:
设置在滑动的时候不要加载数据
谢谢,问题已经解决了
Canra 2015-11-23
  • 打赏
  • 举报
回复
引用 9 楼 scnuxisan225 的回复:
是丢帧还是卡死了?卡死的话就是主线程被占用了,丢帧要看具体情况
卡顿,不是丢帧的
Canra 2015-11-23
  • 打赏
  • 举报
回复
引用 11 楼 qq_22161637 的回复:
你在滑动的时候设置默认图片,给每个图片的地址给一个tag(里面是图片地址),在滑动结束后再加载,好像是listview的busy做处理让他在滑动时候不加载图片
谢谢,问题已经解决了,换了个加载,并且把图片缩小就好了
_deadline 2015-11-23
  • 打赏
  • 举报
回复
我只说问题,只看log就知道,系统回收的太频繁,同时你要知道的是系统回收不是单独线程的,所以主线程会卡
孤独小书生 2015-11-20
  • 打赏
  • 举报
回复
你在滑动的时候设置默认图片,给每个图片的地址给一个tag(里面是图片地址),在滑动结束后再加载,好像是listview的busy做处理让他在滑动时候不加载图片
猴子写代码 2015-11-19
  • 打赏
  • 举报
回复
设置在滑动的时候不要加载数据
scnuxisan225 2015-11-18
  • 打赏
  • 举报
回复
是丢帧还是卡死了?卡死的话就是主线程被占用了,丢帧要看具体情况
sagittarius1988 2015-11-18
  • 打赏
  • 举报
回复
引用 6 楼 Canra 的回复:
引用 5 楼 sagittarius1988 的回复:
[quote=引用 4 楼 Canra 的回复:] [quote=引用 2 楼 sagittarius1988 的回复:] 应该是你listview里显示的问题
代码这里能不能看出来,是不是缓存没有释放,bitmap没有回收的原因么
你还是直接用这个库加载图片吧https://github.com/nostra13/Android-Universal-Image-Loader[/quote]重新做一个加载倒不是问题,就是想找下问题在哪[/quote] ke
引用 6 楼 Canra 的回复:
引用 5 楼 sagittarius1988 的回复:
[quote=引用 4 楼 Canra 的回复:] [quote=引用 2 楼 sagittarius1988 的回复:] 应该是你listview里显示的问题
代码这里能不能看出来,是不是缓存没有释放,bitmap没有回收的原因么
你还是直接用这个库加载图片吧https://github.com/nostra13/Android-Universal-Image-Loader[/quote]重新做一个加载倒不是问题,就是想找下问题在哪[/quote] 可能是onPostExecute里进行了图片的压缩吧,图片的处理都比较耗性能
蒲锦_up 2015-11-18
  • 打赏
  • 举报
回复
分页加载吧 卡顿是一次性加载太多的东西了
Canra 2015-11-18
  • 打赏
  • 举报
回复
引用 5 楼 sagittarius1988 的回复:
引用 4 楼 Canra 的回复:
[quote=引用 2 楼 sagittarius1988 的回复:] 应该是你listview里显示的问题
代码这里能不能看出来,是不是缓存没有释放,bitmap没有回收的原因么
你还是直接用这个库加载图片吧https://github.com/nostra13/Android-Universal-Image-Loader[/quote]重新做一个加载倒不是问题,就是想找下问题在哪
sagittarius1988 2015-11-18
  • 打赏
  • 举报
回复
引用 4 楼 Canra 的回复:
引用 2 楼 sagittarius1988 的回复:
应该是你listview里显示的问题
代码这里能不能看出来,是不是缓存没有释放,bitmap没有回收的原因么
你还是直接用这个库加载图片吧https://github.com/nostra13/Android-Universal-Image-Loader
Canra 2015-11-18
  • 打赏
  • 举报
回复
引用 2 楼 sagittarius1988 的回复:
应该是你listview里显示的问题
代码这里能不能看出来,是不是缓存没有释放,bitmap没有回收的原因么
Canra 2015-11-18
  • 打赏
  • 举报
回复
引用 1 楼 jueshiqicai11 的回复:
图片加载废了时间吧
图片加载用的是一个异步请求,这是一个类似购物车模块
sagittarius1988 2015-11-18
  • 打赏
  • 举报
回复
应该是你listview里显示的问题
UESTC少尉 2015-11-18
  • 打赏
  • 举报
回复
图片加载废了时间吧

80,352

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧