Какие инструменты и методы Android лучше всего подходят для поиска утечек памяти / ресурсов?


Question

У меня разработано приложение для Android, и я нахожусь в разработке приложений для телефона, где все, кажется, работает хорошо, и вы хотите объявить о победе и отправке, но вы знаете, что должны быть какие-то утечки памяти и ресурсов там; и на Android есть только 16 мб кучи, и, по-видимому, это удивительно легко протекает в приложении для Android.

Я оглядывался и до сих пор мог только выкопать информацию о «hprof» и «traceview», а также не получил много положительных отзывов.

Какие инструменты или методы вы столкнулись или разработали и можете поделить, может быть, в проекте ОС?







Ответ от @ hp.android хорошо работает, если вы просто работаете с растровыми фонами, но в моем случае у меня был BaseAdapter обеспечивающий набор ImageView для GridView . Я изменил метод unbindDrawables() как указано, так что условие:

if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
  ...
}

но проблема в том, что рекурсивный метод никогда не обрабатывает дочерние AdapterView . Чтобы решить эту проблему, я сделал следующее:

if (view instanceof ViewGroup) {
  ViewGroup viewGroup = (ViewGroup) view;
  for (int i = 0; i < viewGroup.getChildCount(); i++)
    unbindDrawables(viewGroup.getChildAt(i));

  if (!(view instanceof AdapterView))
    viewGroup.removeAllViews();
}

так что дети AdapterView все еще обрабатываются - метод просто не пытается удалить всех детей (что не поддерживается).

Это не совсем исправляет проблему, так как ImageView управляет растровым изображением, которое не является их фоном. Поэтому я добавил следующее. Это не идеально, но он работает:

if (view instanceof ImageView) {
  ImageView imageView = (ImageView) view;
  imageView.setImageBitmap(null);
}

В целом метод unbindDrawables() будет следующим:

private void unbindDrawables(View view) {
  if (view.getBackground() != null)
    view.getBackground().setCallback(null);

  if (view instanceof ImageView) {
    ImageView imageView = (ImageView) view;
    imageView.setImageBitmap(null);
  } else if (view instanceof ViewGroup) {
    ViewGroup viewGroup = (ViewGroup) view;
    for (int i = 0; i < viewGroup.getChildCount(); i++)
    unbindDrawables(viewGroup.getChildAt(i));

    if (!(view instanceof AdapterView))
      viewGroup.removeAllViews();
  }
}

Я надеюсь, что существует более принципиальный подход к освобождению таких ресурсов.