Утечка this
в конструкторе опасна, потому что объект, которому вы его пропускаете, может начать получать доступ к его элементам еще до завершения работы конструктора, поэтому он может быть не готов. Вы можете получить NPE даже для ненулевых свойств Kotlin или другого странного поведения.
В случае LayoutInflator.inflate
это, похоже, не проблема, хотя бы потому, что построено Android -in-представления часто передают this
как родительский метод inflate()
. Например, конструктор DatePicker создает экземпляр DatePickerSpinnerDelegate, который передает этот экземпляр DatePicker в inflate()
, причем все это происходит до того, как конструктор DatePicker вернулся.
Когда вы передаете представление в качестве родителя в inflate()
, следуя вызову Я вижу две вещи, которые происходят с родителем. Он вызывает getContext()
для этого родителя и вызывает addView()
для этого родителя, если addToRoot
имеет значение true. Поэтому я думаю, что утечка this
безопасна до тех пор, пока вы не переопределите addView()
для выполнения дополнительной работы, которая зависит от членов, которые вы настроили после вызова inflate(). But
addView () also internally calls
requestLayout () and
invalidate () `, поэтому к ним относятся те же проблемы.
В большинстве случаев ваша пользовательская ViewGroup будет подклассом существующего Android класса ViewGroup, поэтому вам не нужно переопределять эти методы.
К сожалению, мы можем вывести это поведение, только проверив код. Не страшно заверять, что документация не гарантирует безопасность, но, насколько я знаю, мы просто должны признать, что это, вероятно, безопасно. Может быть, проблема должна быть открыта на AOSP. Это предупреждение даже не появляется, если вы пишете тот же код на Java, но риск тот же.
Подавление предупреждения не должно означать, что вы игнорируете предупреждение или просто взламываете свой код , Это означает: «Я подтверждаю режим сбоя и проверил, что мой код не будет таким образом сбой». Если бы это было не так, это была бы ошибка компилятора, а не предупреждение. В Kotlin можно использовать аннотацию подавления @Suppress("LeakingThis")
.