Samsung Note 3: утечка памяти активности после нажатия боковой кнопки SPen

Без реализации каких-либо библиотек SDK, связанных с SPen, в расширенном классе AppCompatActivity возникает утечка памяти. Следующая последовательность событий обычно вызывает утечку памяти:

  1. Пользователь нажимает боковую кнопку, которая активирует инструмент Air Command.
  2. Не нажимая ни на один из значков инструмента Air Command, боковая кнопка нажимается снова.
  3. Экран поворачивается, что в данном случае приводит к уничтожению и перезапуску Activity.
  4. Выполнение дампа кучи Java через Android Studio выявляет утечку памяти из-за уничтоженной активности.
  5. Анализатор указывает, что на переменную активности mContext ссылается класс пакета: com.samsung.android.smartclip.SpenGestureManager. Это, скорее всего, вызывает утечку памяти активности.

Есть ли способ очистить ссылку на переменную mContext, хранящуюся в классе SpenGestureManager? Мы надеемся, что это должно позволить сборщику мусора очистить уничтоженную активность.

Эта проблема была обнаружена на следующем устройстве/версии Android (Samsung Galaxy Note 3 Duos):

  • Номер модели: SM-N9002
  • Версия Android: 4.4.2 (КитКат)
  • Версия основной полосы частот: N9002ZNUFNK1
  • Версия ПЗУ: SVA ROM SM-N9002 v9.0

Это же приложение было протестировано на устройстве Samsung Galaxy Note 10.1, которое, похоже, не имеет этой проблемы с утечкой памяти.


person Tjaart    schedule 31.08.2017    source источник


Ответы (1)


Как видно из исходники LeakCanary, это хорошо известная утечка памяти.

SpenGestureManager имеет статическое поле mContext, которое пропускает ссылку на активность. Да, поле STATIC mContext.

Я думаю, что это можно решить с помощью отражения. Это кусок кода, который должен работать:


    // Perform an if-check to see whether this is a Samsung device
    Class clazz = Class.forName("com.samsung.android.smartclip.SpenGestureManager");
    Field mContext = clazz.getDeclaredField("mContext");
    mContext.setAccessible(true);
    mContext.set(null, null);

person azizbekian    schedule 04.09.2017
comment
Ваш подход, кажется, работает очень хорошо, хотя: getDeclaredField("modifiers"), кажется, выдает NoSuchFieldException. Тем не менее, я декомпилировал SpenGestureManager.java из пакета framework2.jar на телефоне, и mContext выглядит так, как будто он не объявлен окончательным. Поэтому я заменил вызов setFinalStatic() на mContext.setAccessible(true) и напрямую позвонил mContext.set(null, null). Утечка памяти, похоже, исчезла. - person Tjaart; 05.09.2017