2

我正在尝试从 imageurl 下载图像来自该 url 的图像是高分辨率图像。当我尝试将此图像加载到 mdpi 的模拟器时,它在所有高分辨率手机中都可以正常工作,它正在抛出内存泄漏例外。

我该如何处理这种情况,我希望在每个屏幕上都有这个图像,所以我将位图声明为全局变量

有什么方法可以在下载时减小图像大小。我使用以下代码下载图像

c1 是对图像视图的引用

bitmap = BitmapFactory.decodeStream((InputStream)new URL(logourltop.get(0)).getContent());
cl.setImageBitmap(bitmap) ;

(或者)

最好在需要时使用 urlimagehelper 项目下载图像

UrlImageViewHelper.setUrlDrawable(cl,logourltop.get(0));

还有一个疑问是我正在通过使用更改同一活动中的视图

setContentView(R.layout.filename).

如果我更改 listitem 上的视图,单击为位图分配的内存将被释放或不释放。(为该视图分配的对象和位图的内存)

你能建议我一个更好的方法来避免内存泄漏吗?

4

3 回答 3

1

您基本上必须下载图像数据,并以流或字节数组的形式使用图像数据,您可以使用BitmapFactory中的便捷方法,它将为您提供一个位图,并且有了这个位图,您可以已经将其直接设置为 ImageView。

确保在单独的线程中从网络执行下载,例如使用AsyncTask .doInBackground()并在 UI 线程上的 ImageView 上设置位图,例如通过在 AsyncTask 的方法onPostExecute()上设置位图或调用Activity.runOnUIThread( ) .

于 2013-03-22T12:24:24.050 回答
0
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

public class downloadimg extends Activity {

//  
private ImageView mImageView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //Find the reference to the ImageView
    mImageView = (ImageView) findViewById(R.id.test_image);

    // You can set a temporary background here
    //image.setImageResource(null);

    // Start the DownloadImage task with the given url
    new DownloadImage().execute("http://demo.imgur.com/CQzlM.jpg");
}


/**
 * Simple functin to set a Drawable to the image View
 * @param drawable
 */
private void setImage(Drawable drawable)
{
    mImageView.setBackgroundDrawable(drawable);
}

public class DownloadImage extends AsyncTask<String, Integer, Drawable> {

    @Override
    protected Drawable doInBackground(String... arg0) {
        // This is done in a background thread
        return downloadImage(arg0[0]);
    }

    /**
     * Called after the image has been downloaded
     * -> this calls a function on the main thread again
     */
    protected void onPostExecute(Drawable image)
    {
        setImage(image);
    }


    /**
     * Actually download the Image from the _url
     * @param _url
     * @return
     */
    private Drawable downloadImage(String _url)
    {
        //Prepare to download image
        URL url;        
        BufferedOutputStream out;
        InputStream in;
        BufferedInputStream buf;

        //BufferedInputStream buf;
        try {
            url = new URL(_url);
            in = url.openStream();



            // Read the inputstream 
            buf = new BufferedInputStream(in);

            // Convert the BufferedInputStream to a Bitmap
            Bitmap bMap = BitmapFactory.decodeStream(buf);
            if (in != null) {
                in.close();
            }
            if (buf != null) {
                buf.close();
            }

            return new BitmapDrawable(bMap);

        } catch (Exception e) {
            Log.e("Error reading file", e.toString());
        }

        return null;
    }

}

}
于 2013-03-22T12:13:40.583 回答
-1

希望这会有所帮助...

public class BitmapResizer {

    public static Bitmap decodeFile(File f,int requiredSize){
    try {
        //decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

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

        //decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {

    }
    return null;
}}
于 2013-03-22T12:28:13.447 回答