【问题标题】:Android - Good practices to avoid Memory leaksAndroid - 避免内存泄漏的良好做法
【发布时间】:2017-05-06 06:19:31
【问题描述】:

您知道避免内存泄漏的良好做法吗?

我目前正在开发一个内存泄漏很少的应用程序,我很难修复它,主要是因为我不知道我需要采取哪些习惯才能避免它们。

例如,目前我遇到了这个问题

    Fatal Exception: java.lang.OutOfMemoryError
Failed to allocate a 1627572 byte allocation with 1293760 free bytes and 1263KB until OOM
 Raw Text
dalvik.system.VMRuntime.newNonMovableArray (VMRuntime.java)
android.view.LayoutInflater.inflate (LayoutInflater.java:429)
com.XX.Dialog.PopupDialog.onCreateView (PopupDialog.java:50)

来自onCreateView中的inflater.inflate(R.layout.dialog_popup, container, false);

Here is the DialogFragment concerned : 

public final class PopupDialog extends DialogFragment {

    public PopupDialog()
    {
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        View view = inflater.inflate(R.layout.dialog_popup, container, false);
        return view;
    }

布局很长,但基本上有 5 个 ImageViews 。这是一个示例:

    <ImageView
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:id="@+id/popup_top_bg_iv"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="false"
    android:layout_alignParentStart="false"
    android:src="@drawable/popup_top_bg"
    android:scaleType="fitXY"
    android:background="@color/transparent" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/popup_top_bg_iv"
    android:background="#ffffff"
    android:layout_alignBottom="@+id/popup_bottom_ll" />

<ImageView
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:id="@+id/popup_top_iv"
    android:src="@drawable/popup_0_top"
    android:scaleType="fitCenter"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="20dp" />

....

所以....我想知道你是否知道:

1.什么可能导致此 dialogFragment 出现内存泄漏错误?

2。 android中有什么好的做法可以避免内存泄漏?

例如对于那个文件,我应该调用

imageView.setImageDrawable(null);

在弹出窗口关闭/活动关闭时的每个 Imageview 上 (R.drawable.* ) ?或者只是当我从 URL(例如使用 Glide)动态加载图像时?

我应该总是将图像的大小调整到我的 Imageview 的尺寸吗? 片段/活动关闭后我到底需要清理什么?

你怎么看?

【问题讨论】:

  • 严格来说,这不是内存泄漏错误。您试图在一个块中分配 1627572 个字节。这可能来自可绘制资源; LogCat 中的完整堆栈跟踪将有助于确定这一点。该块相当于一个 637x637 像素的图像,相当大。我的猜测是您在res/drawable/ 中添加了一些专为更高屏幕密度而设计的内容(例如res/drawable-xhdpi/)。您只剩下 1293760 字节的堆空间这一事实 表明内存泄漏,但它们可能与这段代码相去甚远。
  • 嘿@Co​​mmonsWare 感谢您的响应。 Drawable 文件夹仅包含 .xml 文件。我的大部分 png 已经在 drawable-xhdpi 文件夹中了!
  • 好的,您在该布局中是否有一些相当大的可绘制对象?
  • 保持布局简单并尽可能多地使用资源。在小空间使用时使用小图像。一些 ImageLoader 库可能会帮助您加载图像。 Android 开发者加载图片指南可能对您有所帮助,您可以从官方网站找到。
  • 感谢@JadavLalit 的评论。我实际上已经在使用 Glide 加载图像了。 CommonsWare,我压缩了所有的图像,看看效果如何! :)

标签: android performance memory memory-leaks imageview


【解决方案1】:

经过一番挖掘,我提出了这些解决方案:

https://medium.com/@multidots/glide-vs-picasso-930eed42b81d

  • 切勿将 contextActivity 引用保持为静态。绝不! 否则,即使您需要,您的参考资料可能仍然存在。

  • 避免保留对 ImageView 的引用。销毁视图时回收/清除里面的位图。

  • 如果需要有上下文的引用,请使用context.getApplicationContext();

  • 不要将context.getApplicationContext(); 用于LayoutInflater.from(context);,而是直接使用上下文。

(如果您需要放大视图或需要某些内容的上下文)。 如果您使用 context.getApplicationContext(),如果您动态创建视图,可能会导致一些设计问题。

  • 如果您遇到一些 OutOfMemory 错误,请考虑压缩您的图像!它实际上为我节省了很多 OutOfMemory 错误。您可以使用https://tinypng.com/
  • 默认情况下不要将图像放入文件夹 drawable-xhdpi 而是 drawable-mdpi 因为 drawable-mdpi 是默认文件夹一个。

所以对于我的问题,我只需要压缩图像并将它们放回drawable-mdpi文件夹!现在一切都好!

【讨论】:

    猜你喜欢
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多