内存溢出问题
正在执行的程序是在内存里的,也就是说,我们现在展示的图片也在内存中,那么一张图片到底会占多少内存呢?
可以用以下公式计算
也就是说这张图片占的二进制位如下:
8个二进制位占一个字节,所以
这是这张图加载到内存中占的字节的数量
再÷1024就是kb
再÷1024就是m
然后我们可以看看一屏显示几张图片再做乘法运算,可以粗略计算出一屏图片占用的内存
如果内存占用太多就会出现OutOfMemory的error
我们选择第二种方法,来缩小图片,修改ImageAdapter
public class ImageAdapter extends BaseAdapter<Image> {
public ImageAdapter(Context context, List data) {
super(context, data);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if(view == null){
viewHolder = new ViewHolder();
view = getInflater().inflate(R.layout.item_image,null);
viewHolder.imageView = (ImageView)view.findViewById(R.id.img_item);
view.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) view.getTag();
}
Image image = getData().get(i);
Log.d("Image","id:"+image.getId()+";data:"+image.getData()+";size:"+image.getSize()+
";displayname:"+image.getDisplayName()+";dataTaken:"+image.getDateTaken()+";尺寸:"+image.getWidth()+
"x"+image.getHeight());
//判断并计算图片的缩放比
//200单位是px
int rate = 1;
if(image.getWidth()>IMAGE_MAX_SIZE&&image.getHeight()>IMAGE_MAX_SIZE){
if(image.getWidth()<image.getHeight()){
rate = image.getWidth()/IMAGE_MAX_SIZE;
}else {
rate = image.getHeight()/IMAGE_MAX_SIZE;
}
}
//创建解码图片选项参数
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = rate;
//解码图片得到图片的bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(image.getData(),opts);
Log.d("Image","解码完成,bitmap尺寸为"+bitmap.getWidth()+"x"+bitmap.getHeight()+"bitmap占用内存:"+bitmap.getByteCount());
viewHolder.imageView.setImageBitmap(bitmap);
return view;
}
private static final int IMAGE_MAX_SIZE = 200;
class ViewHolder{
ImageView imageView;
}
}
如果rate=4,那么图片将被缩小为原来的1/4,如果传入了一个比1小的值,程序处理时按1处理
Log
id:8424;data:/storage/emulated/0/Pictures/1527909747288.jpg;size:253447;displayname:1527909747288.jpg;dataTaken:1527909752000;尺寸:1280x1024
解码完成,bitmap尺寸为320x256bitmap占用内存:327680
不同dpi的dp和px转换
看模拟机的信息
1080*1920的单位都是px,420dpi不足480,所以i被划分为320级别
卡的问题
卡的原因只有1个就是主线程太卡,因此我们需要开线程。图库案例先到这,先去学习线程相关内容后再回来解决