Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/206.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将图像从图像URL下载到图像视图_Android_Memory Management_Bitmap - Fatal编程技术网

Android 将图像从图像URL下载到图像视图

Android 将图像从图像URL下载到图像视图,android,memory-management,bitmap,Android,Memory Management,Bitmap,我正在尝试从imageurl下载图像从该url提交的图像是一个高分辨率图像。当我尝试将此图像加载到mdpi模拟器时,它在所有高分辨率手机中都工作正常。它抛出内存泄漏异常 我如何处理这种情况,我希望每个屏幕上都有这个图像,所以我将位图声明为一个全局变量 下载时有没有办法减小图像大小。iam使用以下代码下载图像 c1是对图像视图的引用 bitmap = BitmapFactory.decodeStream((InputStream)new URL(logourltop.get(0)).getCont

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

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

下载时有没有办法减小图像大小。iam使用以下代码下载图像

c1是对图像视图的引用

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

如果需要,最好使用URLMageHelper项目下载图像

UrlImageViewHelper.setUrlDrawable(cl,logourltop.get(0));
还有一个疑问是,我正在使用

setContentView(R.layout.filename).
如果我更改listitem上的视图,请单击为位图分配的内存是否将被释放。(为该视图的对象和位图分配的内存)

您能为我推荐一种更好的方法来避免内存泄漏吗。

import java.io.BufferedInputStream;
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;
    }

}

}
导入java.io.BufferedOutputStream; 导入java.io.FileOutputStream; 导入java.io.InputStream; 导入java.net.URL; 导入android.app.Activity; 导入android.graphics.Bitmap; 导入android.graphics.BitmapFactory; 导入android.graphics.drawable.BitmapDrawable; 导入android.graphics.drawable.drawable; 导入android.os.AsyncTask; 导入android.os.Bundle; 导入android.util.Log; 导入android.widget.ImageView; 公共类下载IMG扩展活动{ // 私有图像视图mImageView; /**在首次创建活动时调用*/ @凌驾 创建时的公共void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //查找对ImageView的引用 mImageView=(ImageView)findViewById(R.id.test\u图像); //您可以在此处设置临时背景 //image.setImageResource(空); //使用给定的url启动DownloadImage任务 新建下载映像()。执行(“http://demo.imgur.com/CQzlM.jpg"); } /** *简单函数,用于将可绘制图像设置为图像视图 *@param可绘制 */ 私有void setImage(可绘制) { mImageView。后退可拉深(可拉深); } 公共类DownloadImage扩展异步任务{ @凌驾 受保护的可抽出式doInBackground(字符串…arg0){ //这是在后台线程中完成的 返回下载图像(arg0[0]); } /** *下载图像后调用 *->这将再次调用主线程上的函数 */ 受保护的void onPostExecute(可绘制图像) { 设置图像(图像); } /** *实际上是从_url下载图像 *@param\u url *@返回 */ 私有可绘制下载图像(字符串\u url) { //准备下载图像 网址; 缓冲输出流输出; 输入流输入; 缓冲输入流buf; //缓冲输入流buf; 试一试{ url=新url(_url); in=url.openStream(); //读取输入流 buf=新的BufferedInputStream(in); //将BufferedInputStream转换为位图 位图bMap=BitmapFactory.decodeStream(buf); if(in!=null){ in.close(); } 如果(buf!=null){ buf.close(); } 返回新的BitmapDrawable(bMap); }捕获(例外e){ Log.e(“读取文件时出错”,e.toString()); } 返回null; } } }
基本上,您必须下载图像数据,并且使用流或字节数组形式的图像数据,您可以使用方便的方法从中获得位图,并且使用此位图,您可以直接将其设置为ImageView

确保在单独的线程中执行网络下载,例如使用并在UI线程的ImageView上设置位图,例如在AsyncTask或调用的方法上设置位图。

希望这将有助于

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;
}}
公共类位图大小调整器{
公共静态位图解码文件(文件f,int requiredSize){
试一试{
//解码图像大小
BitmapFactory.Options o=新的BitmapFactory.Options();
o、 inJustDecodeBounds=true;
解码流(新的FileInputStream(f),null,o);
//找到正确的刻度值。它应该是2的幂。
所需最终整型尺寸=所需尺寸;
内部宽度=o.向外宽度,高度=o.向外高度;
int标度=1;
while(true){

如果(width_tmp/2code没有安全地关闭资源…关闭finally块上的资源。但是,如果位图具有高分辨率图像,则内存溢出错误如何根据设备堆调整图像大小这就是他们发明BitampFactory的原因。选项:使用它找到最佳匹配。在通过的BitmapFactory上e字节数组或流要获取位图,您可以提供选项对象作为参数,该参数将应用于防止内存不足错误…在这种情况下,您肯定希望使用流而不是字节数组。现在它工作正常。但是是否有任何外部库来处理所有与内存相关的问题,我们可以使用该库Y从IVIULLS加载多个位图。很高兴听到我的答案是有用的;-关于一个外部的库,有一个用图像做很多东西(下载和缓存),你可以考虑使用它:下一个代码唯一的答案和下一次的投票……“希望这会有帮助…”用户只想要答案…@WarrenFaithand所有其他搜索答案的人只想复制和粘贴代码,而不需要学习任何东西…真的,支持懒惰一次。。。