简体   繁体   English

使用AsyncTask下载文件的Android应用中的内存泄漏

[英]Memory Leak in Android App Using AsyncTask to Download File

I am having an issue with an apparent memory leak while using the AsyncTask class. 我在使用AsyncTask类时出现明显的内存泄漏问题。 The Android class below is intended to download an image from http and store it into the member variable " Drawable bgImageDrawable ". 下面的Android类旨在从http下载图像并将其存储到成员变量“ Drawable bgImageDrawable ”中。 The function that begins the download process is downloadBackgroundImage() . 开始下载过程的函数是downloadBackgroundImage() After this is run, it appears that the Used Memory size increases by 8MB each time. 运行此命令后,似乎“已用内存”大小每次增加8MB。 I am downloading a jpeg image file that is 800KB, but I am not sure why the Memory increases significantly. 我正在下载一个800KB的jpeg图像文件,但是我不确定为什么内存会显着增加。 Is there an issue with the code below? 下面的代码有问题吗?

public class Example 
{
    private URL bgImageUrl;
    private Drawable bgImageDrawable;

    public Example(String bg)   {
        try {
            this.setBgImageUrl(new URL(bg));
        } 
        catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public Drawable drawableFromUrl(String url, String srcName) throws java.net.MalformedURLException, java.io.IOException  {
        return Drawable.createFromStream(((java.io.InputStream) new java.net.URL(url).getContent()), srcName);
    }

    public void downloadBackgroundImage()    {
        new DownloadFilesTask().execute(getBgImageUrl().toString());
    }

    public void setBgImageDrawable(Drawable bgImageDrawable) {
        this.bgImageDrawable = bgImageDrawable;
    }

    public URL getBgImageUrl() {
        return bgImageUrl;
    }
    public void setBgImageUrl(URL bgImageUrl) {
        this.bgImageUrl = bgImageUrl;
    }

    /* The purpose of this class is to download a file asynchronously. */
    private class DownloadFilesTask extends AsyncTask<String, Integer, Drawable> 
    {
        protected Drawable doInBackground(String... s)       {
            Drawable bgImage = null;
              try  {
                    bgImage = drawableFromUrl(s[0], "src name");
                    return bgImage;
              } 
              catch (MalformedURLException e)             {
                    e.printStackTrace();
              } 
              catch (IOException e)               {
                    e.printStackTrace();
              }

            return bgImage;
         }

         protected void onProgressUpdate(Integer... progress)        {

         }

         protected void onPostExecute(Drawable result)       {
             setBgImageDrawable(result);
         }
     }
}

You convert 800KB jpeg to a drawable. 您将800KB jpeg转换为可绘制对象。 Your jpeg after downloading decoded to a bitmap. 下载后的jpeg解码为位图。 And the bitmap is wraped inside Drawable. 位图包装在Drawable中。 So it's ok that decoded bitmap of 800KB jpeg takes 8MB. 因此,将800KB jpeg的解码位图占用8MB是可以的。

You can use profiler to see what exactly taking so much memory. 您可以使用探查器查看究竟占用了多少内存。 IMHO it's a drawable. 恕我直言,这是一个可绘制的。

It's cause of longer task 这是任务更长的原因

  1. Use Activity context only where there is no other choice and NEVER allow a reference to it in something with a scope greater than the scope of the Activity it references. 仅在没有其他选择的情况下使用“活动”上下文,并且绝不允许在范围大于其所引用的“活动”的范围内对其进行引用。
  2. The Android application framework provides many classes designed to make background threading easier for developers. Android应用程序框架提供了许多旨在使开发人员更容易使用后台线程的类。 For example, consider using a Service or Synadapter instead of a thread/Asyntask/Loader for performing Long-lived asynchronous background queries in conjunction with the Activity lifecycle. 例如,考虑使用服务或Synadapter而不是线程/ Asyntask / Loader来与Activity生命周期一起执行长寿命的异步后台查询。

For this I will suggest you to use the Service or IntentService. 为此,我建议您使用Service或IntentService。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM