kotlin - Как синтетическое свойство инициализирует представление?

Я использовал синтетическое свойство в своем коде. Но мне интересно, как и когда оно фактически инициализирует каждое представление в Android.

Мы просто предоставляем импорт и доступ к каждому представлению по его идентификатору. Когда он выделяет память для объекта просмотра?


person paril    schedule 13.07.2017    source источник
comment
Если вы выполняете инфляцию из XML, при этом выделяется память.   -  person Sufian    schedule 13.07.2017


Ответы (1)


Это достаточно легко исследовать, декомпилировав файл Kotlin, в котором вы используете Kotlin Android Extensions. (Вы можете сделать это, перейдя к Tools -> Kotlin -> Show Kotlin Bytecode, а затем выбрав Decompile на появившейся панели.) Короче говоря, в этом нет ничего волшебного, он просто использует findViewById, а затем приводит View к конкретному типу для вас.

Если вы используете его внутри Activity или Fragment, они кэшируются в Map, так что поиск происходит только один раз. После этого вы оплачиваете только расходы на получение записи карты по идентификатору в качестве ключа.


Вы также можете использовать его на ViewGroup, чтобы найти в нем ребенка с заданным идентификатором, в этих случаях нет кэширования, эти вызовы заменяются простыми вызовами findViewById, которые будут происходить каждый раз, когда эта линия будет достигнута. Этот второй синтаксис выглядит примерно так:

val view = inflater.inflate(...)
view.btnLogin.text = "Login"

И это будет переводиться в нечто похожее на это в байт-коде:

View view = inflater.inflate(...);
Button btnLogin = (Button) view.findViewById(R.id.btnLogin);
btnLogin.setText("Login");

Обратите внимание, что фактические экземпляры View по-прежнему создаются при раздувании макета. Kotlin Android Extensions — это всего лишь синтаксический сахар над findViewById вызовами.

person zsmb13    schedule 13.07.2017
comment
Спасибо за ценный ответ. Но когда вызывается метод _$_clearFindViewByIdCache? - person paril; 13.07.2017
comment
Для Activity это не нужно вызывать, а для Fragment он вызывается внутри метода onDestroyView. - person zsmb13; 13.07.2017