Русский
Русский
English
Статистика
Реклама

Kotlin Android Extensions deprecated. Что делать? Инструкция по миграции

Возможно, вы уже слышали, что Kotlin Android Extensions плагин для Kotlin теперь deprecated.
kotlinx.android.synthetic is no longer a recommended practice. Removing in favour of explicit findViewById

Безусловно, это было очень удобно, особенно если у вас проект полностью на Kotlin. Однако, мир меняется и теперь нужно искать альтернативы. В этой статье мы кратко рассмотрим, что такое плагин Kotlin Android Extension, какие были проблемы с ним и что теперь нам, Android-разработчикам делать. Частично, использовался материал этой статьи. Итак, поехали.

Кратко о Kotlin Android Extensions


Kotlin Android Extensions это плагин для Kotlin, позволяющий восстанавливать view из Activities, Fragments, и Views без написания стандартного бойлерплэйт-кода типа findViewById.
Плагин генерирует дополнительный код, который позволяет получить доступ к view в виде XML, так же, как если бы вы имели дело с properties с именем id, который вы использовали при определении структуры.

Также он создаёт локальный кэш view. При первом использовании свойства, плагин выполнит стандартный findViewById. В последующем, view будет восстановлен из кэша, поэтому доступ к нему будет быстрее.

Если это всё так удобно, то зачем его сделали deprecated?

Проблемы Kotlin Android Extensions


  • Используется глобальный нэйминг идентификаторов. Могут возникнуть ситуации, когда один и тот же идентификатор имеется у разных view в разных лэйаутах соответственно только на этапе работы приложения вы узнаете о том, что использовали не тот id.
  • Возможно использовать только в проектах на Kotlin (кэп)
  • Отсутствует Null Safety. В случае, когда view представлена в одной конфигурации и отсутствует в другой может возникнуть краш, т.к отсутствует обработка таких ситуаций
  • Невозможно использовать в многомодульных проектах. Очень распространённый сценарий: у вас есть модуль UI Kit, хранящий общие UI-компоненты, которые вы хотите переиспользовать в других модулях. До сих пор висит issues которое вряд ли поправят. В таком сценарии обычно используют старый добрый findViewById :(
  • Резюмируя приведённые недостатки, нетрудно понять, что этот подход не идеален хотя, безусловно, очень удобен на небольших проектах. На больших проектах с многомодульной архитектурой и сотнями экранов использование Kotlin Android Extensions уже не кажется идеальным решением.

Альтернативные способы


  • Использование KotterKnife (кек, даже не думайте).
  • Старый добрый FindViewById() уже получше, но так себе.
  • Использование AndroidAnnotations (привет из 2015)
  • View Binding от Google бинго!


View Binding от Google


Итак, победителем в этом списке выглядит ViewBinding от Google (не путайте с DataBinding). Давайте кратко рассмотрим, что это такое.

View Binding это инструмент, который позволяет проще писать код для взаимодействия с view. При включении View Binding в определенном модуле он генерирует binding классы для каждого файла разметки (layout) в модуле. Объект сгенерированного binding класса содержит ссылки на все view из файла разметки, для которых указан android:id

Главные преимущества View Binding это Null safety и Type safety.

Начало работы с View Binding


Начать работать с ViewBinding достаточно просто. Нужно добавить опцию в build.gradle:

android {    ...    buildFeatures {        viewBinding true    }}


После этого можно уже использовать. Каждый сгенерированный binding класс содержит ссылку на корневой view разметки (root) и ссылки на все view, которые имеют id. Имя генерируемого класса формируется как название файла разметки, переведенное в camel case + Binding. Например, для файла разметки result_profile.xml:

<LinearLayout ... >    <TextView android:id="@+id/name" />    <ImageView android:cropToPadding="true" />    <Button android:id="@+id/button"        android:background="@drawable/rounded_button" /></LinearLayout>

Будет сгенерирован класс ResultProfileBinding, содержащий 2 поля: TextView name и Button button.

Использование в Activity


Например у вас вот такой layout:

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://personeltest.ru/away/schemas.android.com/apk/res/android"    xmlns:app="http://personeltest.ru/away/schemas.android.com/apk/res-auto"    xmlns:tools="http://personeltest.ru/away/schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintLeft_toLeftOf="parent"        app:layout_constraintRight_toRightOf="parent"        app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>


Результат работы ViewBinding:

public final class ActivityMainBinding implements ViewBinding {  @NonNull  private final ConstraintLayout rootView;  @NonNull  public final TextView textView;


Использовать viewBinding можно так:
private lateinit var binding: ResultProfileBindingoverride fun onCreate(savedInstanceState: Bundle?) {    super.onCreate(savedInstanceState)    binding = ResultProfileBinding.inflate(layoutInflater)    val view = binding.root    setContentView(view)}


И теперь, после того, как получили ссылки на view:

binding.name.text = viewModel.namebinding.button.setOnClickListener { viewModel.userClicked() }


Если вы используете ViewBinding во фрагменте и держите ссылку на binding во фрагменте (а не только в методе onCreateView()) то не забывайте очищать ссылки в методе onDestroyView().

Пример:
private var _binding: ResultProfileBinding? = null// This property is only valid between onCreateView and// onDestroyView.private val binding get() = _binding!!override fun onCreateView(    inflater: LayoutInflater,    container: ViewGroup?,    savedInstanceState: Bundle?): View? {    _binding = ResultProfileBinding.inflate(inflater, container, false)    val view = binding.root    return view}override fun onDestroyView() {    super.onDestroyView()    _binding = null}


Это необходимо делать из-за жизненного цикла фрагмента и view:
image

В целом, переключиться на ViewBinding достаточно не сложно, хотя и жаль, что Kotlin Android Extensions объявлен deprecated. Не забудьте присоединиться к нам в Telegram, а на платформе AndroidSchool.ru публикуются полезные материалы для Android-разработчика и современные туториалы.

Полезные ссылки:

Источник: habr.com
К списку статей
Опубликовано: 03.11.2020 00:14:12
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Разработка под android

Android development

Viewbinding

Kotlin

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru