浅谈Android多图(包括大图)上传时的内存处理,防止内存溢出。

Android多图上传时,为了防止内存溢出,基本只要做好两点就好了,一是及时释放已经上传完的图片,以及在对图片处理时,必须是一张一张来,因为对图片的处理过程是最容易OOM的。


下面有简单的代码说明下,


1、首先,图片的model,

ImageBean


model中保存bitmap对象,然后写好回收方法。

然后,上传大致分为路径上传,还有压缩后以byte[]的方式上传,

所以也要有path和byte[]


    public String path;
    public Bitmap bitmap;
    public byte[] result;
    public Bitmap getBitmap() {
        if (bitmap == null || bitmap.isRecycled()) {
            try {
                //bitmap = MyBimp.revitionImageSize(path, rotation);
                bitmap = MyBimp.getBitmapFromFile(path, rotation);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return bitmap;
    }

    public void recy() {
        if (bitmap != null) {
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
            bitmap = null;
        }
        if (result != null)
            result = null;
    }

    public static byte[] Bitmap2Bytes(Bitmap image, long size) {
        try {
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                long max = 1024 * 1024 + 3072;
                if (size > max) {
                    int options = 100;
                    while (baos.toByteArray().length > (size * 0.8)) {
                        baos.reset();
                        options -= 10;
                        image.compress(Bitmap.CompressFormat.JPEG, options, baos);
                    }
//                    Log.i("TAG", "Utils bitmap option " + options);
                    if (image.isRecycled())
                        image.recycle();

                    return baos.toByteArray();
                } else {
                    return baos.toByteArray();
                }
            } catch (NullPointerException ex) {
                ex.printStackTrace();
            }
        } catch (OutOfMemoryError ex) {
            ex.printStackTrace();
        }
        return null;
    }
<pre name="code" class="java">    public static Bitmap getBitmapFromFile(String path, int rotation) throws IOException {
        if (path == null)
            return null;
        try {
            try {
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(
                        new File(path)));
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(in, null, options);
                in.close();
                WeakReference<Bitmap> weakReference = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path));
                if (weakReference.get() != null) {
                    Bitmap bitmap = Bitmap.createScaledBitmap(weakReference.get(), options.outWidth, options.outHeight, true);
                    if (rotation != 0 && bitmap != null) {
                        Matrix m = new Matrix();
                        m.setRotate(rotation);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
                    }
                    return bitmap;
                }
            } catch (NullPointerException ex) {
                ex.printStackTrace();
            }
        } catch (OutOfMemoryError ex) {
            ex.printStackTrace();
        }
        return null;
    }


 压缩程度根据自己项目实际情况来控制。 

2、从相册读取图片,应该只读取了手机中图片的路径等相关信息,然后压缩显示,这些代码往上非常多。

目的只有一个,不占用多余的内存,

所以只有真正要上传的图片,才会生成完整的bitmap对象或byte[]数组。

可以创建一个全局的MyBimp类,用来管理相册图片,已选择的图片等等。

 public static ArrayList<ImageBean> tempSelectBitmap = new ArrayList<ImageBean>(); 

选择完图片后,应该是一个List<ImageBean>数组。3、上传,保证单例上传,然后每上传完一个调用model中的回收方法就好了,

public class UploadTool {
    private static UploadTool uploadTool = null;

    private UploadTool() {
    }

    public static UploadTool getInstance() {

        if (uploadTool == null) {
            uploadTool = new UploadTool();
        }
        return uploadTool;
    }

    int len;// = MyBimp.tempSelectBitmap.size();
    List<ImageModel> list = new ArrayList<>();
    int position;

    private synchronized void upload(final int next, final onUploadImagesListenter listenter) {
        listenter.onProgressUpdate(next, len);
        if (next < len) {
            ImageBean item = MyBimp.tempSelectBitmap.get(next);
            if (next > 0) {
                MyBimp.tempSelectBitmap.get(next - 1).recy();
            }
            if (!item.isLarge) {
                item.getBitmapLocal(new ImageBean.onBitmapLoadListener() {
                    @Override
                    public void onBitmapLoad(byte[] result) {
                        if (result != null) {
                            //以byte[]上传
                        } else {
                            String error = "数据错误";
                            listenter.onUploadDone(list, error);
                        }
                    }
                });
            } else {
                //以路径上传  一般长图会以这种方式上传
            }
        }
    }

    public void uploadImages(final onUploadImagesListenter listenter) {
        len = MyBimp.tempSelectBitmap.size();
        position = 0;
        upload(0, listenter);
    }


    public interface onUploadImagesListenter {
        void onUploadDone(List<ImageModel> imageModelList, String error);

        void onProgressUpdate(int position, int tatol);
    }
}

具体的上传方法没有写进来,这个根据自己需求不同有很多种不同的方式,比如第三方的sdk。


源码:https://github.com/kiwilll/Album-and-Picture-upload


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值