2014-10-07 4 views
6

я нашел статью "Avoiding memory leaks", в котором говорится, что следующий код:Понимание утечки памяти в приложении Android

private static Drawable sBackground; 

@Override 
protected void onCreate(Bundle state) { 
    super.onCreate(state); 

    TextView label = new TextView(this); 
    label.setText("Leaks are bad"); 

    if (sBackground == null) { 
    sBackground = getDrawable(R.drawable.large_bitmap); 
    } 
    label.setBackgroundDrawable(sBackground); 

    setContentView(label); 
} 

не является хорошей идеей, так как:

При изменении ориентации экрана система по умолчанию уничтожит текущую активность и создаст новую, сохранив ее состояние . При этом Android перезагрузит пользовательский интерфейс приложения из ресурсов .

Так выше код:

... просачивается первое действие, созданный при первом изменении ориентации экрана. Когда Drawable прикреплен к представлению, вид устанавливается как обратный вызов для выделенного объекта. В фрагменте кода выше, это означает, что рисуем имеет ссылку на TextView, который сам по себе имеет ссылку на деятельности (Context), который в свою очередь имеет ссылки на почти все (в зависимости от вашего кода.)

Но, когда изменения ориентации экрана, метод setBackgroundDrawable(Drawable background) называется, который, в свою очередь, вызывает:

background.setCallback(this); 

метод Drawable.setCallback() является определяемом следующим образом:

public final void setCallback(Callback cb) { 
    mCallback = new WeakReference<Callback>(cb); 
} 

Итак, теперь фон должен выпустить старую ссылку на предыдущий TextView и создать новую ссылку на новый TextView.

Таким образом, кажется, что изменение ориентации экрана утечки ссылки только до тех пор, пока активность не будет создана.

Куда я иду не так?

+2

В дополнение к правильному ответу, вид статичности в Деятельности должен сделать вас инстинктивно нездоровым (см. «Запах кода») и передать «this» или «Context» или что-нибудь еще, ссылающееся на «Activity» на объект, который вы не можете напрямую контролировать время жизни, и ** гарантировать **, что это, самое большее, до тех пор, пока 'Активность', должно заставить вас рвать на месте. – Simon

+0

Да, ясно. Спасибо @Simon – GVillani82

+0

Ромен Гай объясняет сценарии утечки памяти в комментариях к оригиналу [сообщение в блоге] (http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on -android /). – corsair992

ответ

11

Вы абсолютно правы. Однако есть один тонкий момент: статья от . Тогда реализация setCallback была different:

Android < = 2.3.7:

public final void setCallback(Callback cb) { 
    mCallback = cb; 
} 

Android> = 4.0.1:

public final void setCallback(Callback cb) { 
    mCallback = new WeakReference<Callback>(cb); 
} 

Grepcode не обнаруживающей исходный код промежуточных версий, это единственный способ, который я мог бы быстро найти.


Итак, опять же, вы абсолютно правы в данном конкретном случае (если вы ориентируетесь> 14, что есть). Тем не менее, по-прежнему очень важно действительно думать о том, что на самом деле происходит, когда вы сохраняете статическую ссылку на такие предметы (как и вы). Существует множество случаев, когда вы, конечно, можете просачивать Context.

+0

точно, что я проверял – njzk2

+2

Вы правы! Спасибо за ответ – GVillani82

Смежные вопросы