Android ListView,Gridview动态加载释放图片资源

在Android开发App中经常会用到ListView和Gridview的item中加载图片显示的情况。但是如果图片多了就会遇到内存溢出的情况,及时你对图片做了缩放处理但是图片张数多了还是一样的会内存溢出。所以这个时候就需要我们动态的释放和加载图片资源。附件中是小弟根据自己的想法实现的动态加载和释放图片,但是有个图片不能动态刷新的问题未能解决。欢迎各位相继完善、探讨和吐糟。若各位有新的想法或实现请发小弟邮箱(592421989@qq.com)一份,小弟学习一下。各位下载项目后在手机SD卡DCIM/Camera/文件夹下可以放300-500张高清图片,就可以测试了

以下是小弟实现的代码块:

MainActivity.java

package com.example.bitmaprecycledemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnScrollListener {

 private GridView mGridView;
 private List<ImageBean> imageList;
 private Bitmap defaultBitmap;
 private final int UPDATE_IMAGE = 0;
 private int firstVisibleItem;
 private int visibleItemCount;
 private int totalItemCount;
 private int lastVisibleItem;
 private boolean isScrollDone;
 private boolean isFirstShow = true;
 private MyAdapter myAdapter;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mGridView = (GridView) findViewById(R.id.mGridView);
  mGridView.setOnScrollListener(this);
  getImageList();
  myAdapter = new MyAdapter();
  mGridView.setAdapter(myAdapter);
  loadImage();
 }

 @Override
 public void onScroll(AbsListView view, int firstVisibleItem,
   int visibleItemCount, int totalItemCount) {
  this.firstVisibleItem = firstVisibleItem;
  this.visibleItemCount = visibleItemCount;
  this.totalItemCount = totalItemCount;
  lastVisibleItem = firstVisibleItem + visibleItemCount;
  System.out.println(String.format("onScroll--------firstVisibleItem=%d && visibleItemCount=%d && totalItemCount=%d",firstVisibleItem, visibleItemCount,totalItemCount));
  isScrollDone = false;
  if(isFirstShow && imageList!= null && imageList.size() > 0 && totalItemCount > 0){
   isFirstShow = false;
   loadImage();
  }
 }

 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState) {
  System.out.println("onScrollStateChanged--------");
  isScrollDone = true;
  mHandler.sendEmptyMessageDelayed(UPDATE_IMAGE, 2000);
 }

 private void getImageList(){
  String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"DCIM/Camera/";
  System.out.println(ROOT_PATH);
  File file = new File(ROOT_PATH);
  File[] files = file.listFiles();
  System.out.println(files.length);
  imageList = new ArrayList<ImageBean>();
  defaultBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image_prompt);
  for (File tempFile : files) {
   ImageBean mImageBean = new ImageBean();
   mImageBean.imagePath = tempFile.getPath();
   mImageBean.imageName = tempFile.getName();
   mImageBean.imageBitmap = defaultBitmap;
   imageList.add(mImageBean);
  }
 }
 
 class MyAdapter extends BaseAdapter{

  @Override
  public int getCount() {
   // TODO Auto-generated method stub
   return imageList.size();
  }

  @Override
  public Object getItem(int position) {
   // TODO Auto-generated method stub
   return imageList.get(position);
  }

  @Override
  public long getItemId(int position) {
   // TODO Auto-generated method stub
   return position;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
   System.out.println("getView--->"+position);
   convertView = View.inflate(MainActivity.this, R.layout.image_item, null);
   ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
   iv.setBackgroundDrawable(new BitmapDrawable(imageList.get(position).imageBitmap));
   imageList.get(position).iv = iv;
   TextView tv = (TextView) convertView.findViewById(R.id.tv);
   tv.setText(imageList.get(position).imageName);
   return convertView;
  }
 }
 
 /**
  * 读取图片文件到bitmap中
  * @param filePath
  * @param size 规定文件大小(KB)
  * @return
  */
 public Bitmap getBitmapForPath(String filePath,int size){
  File f = new File(filePath);
  if(!f.exists()){
   return null;
  }
  BitmapFactory.Options options = new BitmapFactory.Options();
  InputStream is = null;
  try {
   is = new FileInputStream(f);
   int fileSize = is.available();
   System.out.println(f.getName()+"-->"+fileSize/1000+"KB");
   //如果文件大于15K就缩放
   if(fileSize/1000 > size)
   {
    int sampleSize = fileSize/(size*1000);
    options.inSampleSize=sampleSize;
   }
  } catch (Exception e) {
   e.printStackTrace();
   return null;
  }
  return BitmapFactory.decodeStream(is,null,options);
 }
 
 Handler mHandler = new Handler(){
  @SuppressLint("HandlerLeak")
  public void handleMessage(android.os.Message msg) {
   switch (msg.what) {
   case UPDATE_IMAGE:
    System.out.println("mHandler...");
    if(isScrollDone){
     releseImage();
     loadImage();
    }
    break;

   default:
    break;
   }
  };
 };
 
 private void releseImage(){
  System.out.println("releseImage...");
  for(int i = firstVisibleItem - mGridView.getNumColumns();i>=0;i--){
   ImageBean bean = imageList.get(i);
   if(bean.imageBitmap != null && bean.imageBitmap != defaultBitmap){
    Bitmap tempBitmap = bean.imageBitmap;
    bean.imageBitmap = defaultBitmap;
    tempBitmap.recycle();
    tempBitmap = null;
   }
  }
  System.gc();
  for(int i = lastVisibleItem + mGridView.getNumColumns();i<totalItemCount;i++){
   ImageBean bean = imageList.get(i);
   if(bean.imageBitmap != null && bean.imageBitmap != defaultBitmap){
    Bitmap tempBitmap = bean.imageBitmap;
    bean.imageBitmap = defaultBitmap;
    tempBitmap.recycle();
    tempBitmap = null;
   }
  }
  System.gc();
 }
 
 private void loadImage(){
  System.out.println("loadImage...");
  for(int i = firstVisibleItem;i<lastVisibleItem;i++){
   ImageBean bean = imageList.get(i);
   if(bean.imageBitmap != null){
    bean.imageBitmap = getBitmapForPath(bean.imagePath, 130);
    bean.iv.setBackgroundDrawable(new BitmapDrawable(getResources(), bean.imageBitmap));
   }
   if(myAdapter != null){
    System.out.println("myAdapter.notifyDataSetChanged()...");
    myAdapter.notifyDataSetChanged();
   }
  }
 }
 
 @Override
 protected void onDestroy() {
  
  for(int i = 0;i<imageList.size();i++){
   ImageBean bean = imageList.get(i);
   if(bean.imageBitmap != null){
    bean.imageBitmap.recycle();
    bean.imageBitmap = null;
   }
  }
  if(defaultBitmap != null){
   defaultBitmap.recycle();
   defaultBitmap = null;
  }
  super.onDestroy();
 }
}

ImageBean.java

package com.example.bitmaprecycledemo;

import android.graphics.Bitmap;
import android.widget.ImageView;

public class ImageBean {
 public String imagePath;
 public Bitmap imageBitmap;
 public String imageName;
 public ImageView iv;
}

activity_main.xml

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <GridView
        android:id="@+id/mGridView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:numColumns="4"
        android:verticalSpacing="5dip"/>

</RelativeLayout>

 

image_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="100dip"/>


    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:lines="2"/>

</LinearLayout>

 

附件下载地址:点击打开链接

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值