Proper onDestroy() / How to avoid memory leaks

后端 未结 1 1715
旧巷少年郎
旧巷少年郎 2020-12-23 08:57

I read a number of articles on how to avoid memory-leaks in Android, but i\'m still not quite sure if I got it right.

  1. My Application consists of a single
相关标签:
1条回答
  • 2020-12-23 09:23

    Q1. You've taken this out of context (no joke intended :)

    If you see the original article, the leak actually occurs in the next fragment of code where the Bitmap field is introduced. Roman then clearly explains why it leaks. The code you have shown will NOT leak.

    http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/

    Q2. 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. The code you've shown doesn't leak as far as I can see since nothing has a context reference with a scope greater than your Activity. Do you suspect that it does?

    Q3. When using Bitmaps, static references or not, I am in the habit of unbinding Bitamps from Views in onPause() (remember onDestroy() is not guaranteed but it's kind of irrelevant as if you're being destroyed, your process is killed so GC isn't a concern). The linked article also explains how to do this. I have made it a template pattern for any of my Activities handling Bitmaps.

    [EDIT]

    Sorry, I just checked. The article does not show how to unbind. Here's the pattern I use:

    @Override
    protected void onPause()
    {
            super.onPause();
    
            unbindDrawables(findViewById(R.id.mainLayout));
            System.gc();
    }
    
    
    @Override
    protected void onDestroy()
    {
            super.onDestroy();
    
            unbindDrawables(findViewById(R.id.mainLayout));
            System.gc();
    }
    
    private void unbindDrawables(View view)
    {
            if (view.getBackground() != null)
            {
                    view.getBackground().setCallback(null);
            }
            if (view instanceof ViewGroup && !(view instanceof AdapterView))
            {
                    for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
                    {
                            unbindDrawables(((ViewGroup) view).getChildAt(i));
                    }
                    ((ViewGroup) view).removeAllViews();
            }
    }
    

    mainLayout is the root view of the Activity layout.

    I include onDestroy() since I might manually finish() my Activity.

    Note. Calling system.gc() is a complex subject and you might want to omit it. There are some good discussions on here why it might not be a good thing to do, principally concerned with performance. However, in my view, when an activity is being destroyed, hinting that now is a good time to perform GC can do no harm. The inefficiency of calling it unnecessarily will be lost in the overheads of destroying an activity.

    0 讨论(0)
提交回复
热议问题