Android-避免内存泄漏的良好实践

Android-避免内存泄漏的良好实践,android,performance,memory,memory-leaks,imageview,Android,Performance,Memory,Memory Leaks,Imageview,您知道避免内存泄漏的良好做法吗? 我目前正在开发一款几乎没有内存泄漏的应用程序,我很难修复它,主要是因为我不知道我需要养成哪些习惯才能避免它们 比如说,现在我得到这个问题, Fatal Exception: java.lang.OutOfMemoryError Failed to allocate a 1627572 byte allocation with 1293760 free bytes and 1263KB until OOM Raw Text dalvik.system.V

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

我目前正在开发一款几乎没有内存泄漏的应用程序,我很难修复它,主要是因为我不知道我需要养成哪些习惯才能避免它们

比如说,现在我得到这个问题,

    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)
来自
充气机。充气(R.layout.dialog\u弹出窗口,容器,false)在创建视图的
onCreateView

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个图像视图。以下是一个示例:

    <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" />
当弹出窗口关闭/活动关闭(R.drawable.*)时,在每个Imageview上?或者当我从URL动态加载图像时(比如Glide)

我是否应该始终将图像调整为Imageview的尺寸? 片段/活动关闭后,我到底需要清理什么


你觉得怎么样

经过一番挖掘,我得出了以下解决方案:

  • 您可以使用泄漏金丝雀来跟踪内存泄漏()
  • 或者Android studio的内存监视器:
  • 使用库加载您的图像,如毕加索或Glide。就我个人而言,我更喜欢滑翔

  • 切勿将上下文的活动的引用保持为静态。从未! 否则,即使您需要,您的参考资料也可能仍然存在

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

  • 如果需要对上下文进行引用,请使用
    context.getApplicationContext()

  • 不要使用
    context.getApplicationContext()用于
    LayoutInflater.from(上下文)但直接与上下文关联

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

  • 如果您从内存错误中得到一些,请考虑压缩您的图像!它实际上为我节省了很多OutOfMemory错误。你可以用
  • 默认情况下,不要将图像放入文件夹drawable xhdpi,而是drawable mdpi,因为drawable mdpi是默认文件夹

因此,对于我的问题,我只需要压缩图像,并将它们放回可绘制mdpi文件夹!现在一切都好了

严格来说,这不是内存泄漏错误。您正试图在块中分配1627572字节。这可能来自可提取资源;LogCat中的完整堆栈跟踪将有助于确定这一点。该块相当于637x637像素的图像,相当大。我的猜测是,您在
res/drawable/
中添加了一些设计用于更高屏幕密度的内容(例如,
res/drawable xhdpi/
)。您只剩下1293760字节的堆空间这一事实是内存泄漏的迹象,但它们可能与此代码相去甚远。Drawable文件夹仅包含.xml文件。我的大多数PNG已经在drawable xhdpi文件夹中了!好的,你们有一些相当大的可绘制的,你们是在那个布局中引用的吗?只要保持布局简单,并尽可能多地使用你们需要的资源。在小空间中使用时,请使用小图像。一些ImageLoader库可能会帮助您加载图像。Android开发者指南加载图片可能会对你有所帮助,你可以在官方网站上找到。谢谢@JadavLalit的评论。我实际上已经在使用Glide加载图像了。Commonware,我压缩了所有的图像,将看到它是如何运行的!:)
imageView.setImageDrawable(null);