从服务器下载Android的形象和保存到SD卡,而无需使用BitmapFactory [英] Android download image from server and save to sdcard without using BitmapFactory

查看:142
本文介绍了从服务器下载Android的形象和保存到SD卡,而无需使用BitmapFactory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建使用从服务器下载图像,并显示到列表视图的应用程序。我提出的问题是内存泄漏,并让我的应用程序崩溃。我正在寻找在Android的博客像这样链接,它表现出一个伟大的想法,但它仍不足以与多线程做到这一点。机器人的一些设备可以使用它但一些设备只能处理是单线程,有时根本无法工作。

我的应用程序有许多活动,他们每个人都有需要显示的图像越快越好一个列表视图。通过谷歌IO 2012,他们使用缓冲区来保存原始图像到SD卡,它解决问题的内存泄漏,但它使加载很慢,因为需要下载的图片过大。

我的问题是:?有没有什么办法与写入图像一起缩放图像到SD卡 我找出一些可能的解决方案是使用跳过字节的InputStream对象,我能够找到宽度和高度也每次我需要下载图像的像素位。

下面code是使用在2012年谷歌的IO,并与多线程工作得很好,在我的情况下,我在后台4线程中运行。

 私人无效downloadAndWriteFile(最后的字符串URL,最终的文件的文件)抛出的OutOfMemoryError {
    的BufferedOutputStream了= NULL;

    尝试 {
        HttpURLConnection的康恩=(HttpURLConnection类)新的网址(URL).openConnection();
        conn.setDoInput(真正的);
        conn.connect();

        在=新的BufferedInputStream(conn.getInputStream(),IO_BUFFER_SIZE_BYTES)最后的InputStream; //缓冲区大小1KB
        OUT =新的BufferedOutputStream(新的FileOutputStream(文件),IO_BUFFER_SIZE_BYTES);

        INT B:
        而((二= in.read())!=  -  1){
            out.write(B);
        }
        out.close();
        conn.disconnect();
    }
    赶上(例外五){
        Log.e(TAG,!! downloadAndWriteFile+ e.getMessage());
        file.delete();
    }
}
 

解决方案

1)使用设置你的图像以释放与此相关的位图的原生对象,疏通参考像素数据之前,下面的code。它只是允许其作为垃圾进行回收,如果没有其他的引用。

  BitmapDrawable绘制=(BitmapDrawable)myImage.getDrawable();
点阵位图= drawable.getBitmap();
如果(位图!= NULL)
{
    bitmap.recycle();
}
 

2)使用此方法,以减少在存储器位图的大小:

  / **
 *德$ C $连拍影像和扩展它来减少内存消耗
 *
 * @参数文件
 * @参数requiredSize
 * @返回
 * /
公共静态位图德codeFILE(档案文件,INT requiredSize){
    尝试 {

        //德code图像尺寸
        BitmapFactory.Options O =新BitmapFactory.Options();
        o.inJustDe codeBounds = TRUE;
        BitmapFactory.de codeStream(新的FileInputStream(文件),空,O);

        //我们希望新的大小扩展到

        //找到正确的比例值。它应该是2的幂。
        INT width_tmp = o.outWidth,height_tmp = o.outHeight;
        int标= 1;
        而(真){
            如果(width_tmp / 2'; requiredSize
                    || height_tmp / 2版; requiredSize)
                打破;
            width_tmp / = 2;
            height_tmp / = 2;
            规模* = 2;
        }

        //德code与inSampleSize
        BitmapFactory.Options O2 =新BitmapFactory.Options();
        o2.inSampleSize =规模;

        BMP位= BitmapFactory.de codeStream(新的FileInputStream(文件),
                空,O2);

        返回BMP;

    }赶上(FileNotFoundException异常E){
    } 最后 {
        System.gc()的;
    }
    返回null;
}
 

I am trying to create an application that use to download image from server and show it into listview. The problem that I made was the leak of memory and make my application crash. I was searching in Android blog such as this link, it show a great idea but it still not enough to do it with multiple thread. Some device of android can work with it but some device can only handle in the single thread and sometimes it cannot work at all.

My application has many activity and each of them has a Listview that need to display image quick as possible. Through the Google IO 2012 they use buffer to save the original image to SD Card and it solve the problem Leak memory but it make loading so slow since the image that need to download was too big.

My question is: Is there any way to scale image together with write image to SD Card? I figure out some possible solution is to use Skip byte in the inputstream object and I was able to find Width and Height also Bit per pixel of the image that I need to download.

The following code was use in Google IO 2012 and it work well with multiple threading, in my case I have 4 thread running in the background.

private void downloadAndWriteFile(final String url, final File file) throws OutOfMemoryError {
    BufferedOutputStream out = null;

    try {
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setDoInput(true);
        conn.connect();

        final InputStream in = new BufferedInputStream(conn.getInputStream(), IO_BUFFER_SIZE_BYTES);    // buffer size 1KB
        out = new BufferedOutputStream(new FileOutputStream(file), IO_BUFFER_SIZE_BYTES);

        int b;
        while ((b = in.read()) != -1) {
            out.write(b);
        }
        out.close();
        conn.disconnect();
    }
    catch (Exception e) {
        Log.e(TAG, "!!downloadAndWriteFile " + e.getMessage());
        file.delete();
    }
}

解决方案

1) use the following code before setting your images to free the native object associated with this bitmap, and clear the reference to the pixel data. It simply allows it to be garbage collected if there are no other references.

BitmapDrawable drawable = (BitmapDrawable) myImage.getDrawable();
Bitmap bitmap = drawable.getBitmap();
if (bitmap != null)
{
    bitmap.recycle();
}

2) use this method to reduce the size of bitmap in memory:

/**
 * decodes image and scales it to reduce memory consumption
 * 
 * @param file
 * @param requiredSize
 * @return
 */
public static Bitmap decodeFile(File file, int requiredSize) {
    try {

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(file), null, o);

        // The new size we want to scale to

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < requiredSize
                    || height_tmp / 2 < requiredSize)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;

        Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(file),
                null, o2);

        return bmp;

    } catch (FileNotFoundException e) {
    } finally {
        System.gc();
    }
    return null;
}

这篇关于从服务器下载Android的形象和保存到SD卡,而无需使用BitmapFactory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆