Юрий в значительной степени прав.
Моя служба запускает поток, который содержит обратный вызов, и когда поток завершает свою работу, он вызывает обратный вызов, и поток завершается. Когда вызывается обратный вызов, он может выполнить небольшую работу в моей Деятельности, а затем вернуться, и в этот момент у меня нет указателей в процессе «Активность» на обратный вызов.
Однако объект обратного вызова в Activity будет продолжать указываться системой привязки Android до тех пор, пока соответствующий объект обратного вызова в Сервисе не будет собран мусором.
Если объект обратного вызова в процессе Activity доминирует над некоторыми другими объектами, которые занимают много памяти, то я трачу память в своем процессе Activity без всякой уважительной причины и даже могу получить ошибку OutOfMemoryError. Решение состоит в том, чтобы создать простой метод в моем классе обратного вызова под названием destory()
, чтобы обнулить все поля обратного вызова и вызвать этот метод, когда я закончу с обратным вызовом.
Если класс обратного вызова является нестатическим внутренним классом, вы можете подумать о том, чтобы заменить его статическим внутренним классом и передать родительский класс в конструктор, таким образом, вы можете также обнулить это в destory()
способ.
Это вызывает интересную мысль, если родительский класс нестатического внутреннего класса обратного вызова - это Activity, и изменение конфигурации происходит (например, поворот экрана) после того, как обратный вызов отправляется через связыватель, но до его вызова тогда обратный вызов будет указывать на старый объект Activity при запуске!
Обновление : я обнаружил этот код в Binder.java, конечно, он отключен, но было бы неплохо, если бы они упоминали подобные вещи в Javadocs.
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}