Почему findViewById(); не лучшее решение для связывания

281
15 июня 2017, 05:06

В большинстве книг авторы используют этот метод. Слышал что это далеко не самое лучшее решение есть ли альтернатива и какие могут быть последствия. Спасибо.

Answer 1

Проблема связывания через findViewById в том, что разработчик сам отвечает за написание соответствующего кода и за соответствия типов при приведении. Также хочется более простого (автоматизированного) способа накладывания данных модели на представление. Вроде бы ничего сложного, но куча дополнительных строк в onCreate и при заполнении представления данными, в которых можно ошибиться, а также потраченное время на написание оных - причина создавать альтернативные методы.

Если говорить об официальном способе, то это Android Data Binding Library от Google. Решение свежее, но быстро набирает популярность. Данная библиотека позволяет как избежать кода с findViewById, так и устраняет (в большинстве случаев) код для заполнения (!!) данными из модели. И, если я не ошибаюсь, уже есть (или еще на стадии разработки) двухстороннее связывание, что позволяет как автоматически обновлять View при изменении данных, так и наоборот (при изменении данных пользователем во View, меняются данные в объектах модели).

https://developer.android.com/topic/libraries/data-binding/index.html

Очень популярна сторонняя библиотека ButterKnife. Она в свою очередь используется в качестве синтаксического сахара (замена findViewById и setOnClickListener). Также есть некоторые механизмы для изменения свойств View при определенных условиях.

http://jakewharton.github.io/butterknife/

Как таковых минусов данных альтернатив я не встречал. Зависит все от того, какой проект и какая глубина использования данных библиотек в нем. Например, если использовать заполнение данными автоматически с помощью первой библиотеки, то появляется частичный код модели в xml-файле Вашего View. Для кого-то это покажется странным, кто-то найдет в этом способ инкапсулировать простейшие строки типа textView.setText(user.getName()).

Answer 2

Смотря в каком контексте это считать не лучшим решением. Этот метод используется со времён появления Андроид и ничего криминального в нём нет. Если он вас устраивает, то не нужно ничего менять.

Есть мнение, что он работает медленно из за того, что при каждом вызове проходит по всей структуре вью в поисках нужного id. Но вы это заметите, только на очень большом количестве вью, или если используеье этот метод не правильно. В подтверждении этому имеется исследование Dan Lew датированное далёким 2013-м годом.

Если же считать это не лучшим решением в плане количества написанного кода для связывания вью с кодом, то тут есть решение без использования сторонних библиотек. Определите этот метод в базовом классе активити и наследуйте ваши активити от неё:

@SuppressWarnings("unchecked")
public <T extends View> T fvbi(@IdRes int resId) {
    return (T) findViewById(resId);
}

Использовать так:

TextView tvInfo = fvbi(R.id.tvInfo);

Код становится немного короче и нет нудного приведения классов.

Есть и другие альтернативы, в виде сторонних библиотек.

  • ButterKnife только вот кода с ним едва ли становится меньше, и под капотом используется тот же самый fingViewById(). Так что улучшения производительности вы вряд ли увидете.
  • Data Binding Library официальная библиотека от Google. Довольно удобная и большая, и замена fingViewById() лишь малая часть её функционала.
  • Бонус. Если вы пишете на Kotlin, то можно использовать Kotlin Android Extensions

Лично я использую вариант с базовой активити и функцию fvbi(), что меня вполне устраивает.

READ ALSO
Как в приоритетной очереди найти и удалить запись?

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

Можно ли реализовать в данном примере поиск и удаление одной записи?

317
Как привязать приложение к аккаунту Google?

Как привязать приложение к аккаунту Google?

Нужно привязать приложение к аккаунту Google, чтобы при смене девайса или на разных девайсах с одним аккаунтом все работалоКак это делается?...

486
Отслеживание нажатия клавиш в фоне

Отслеживание нажатия клавиш в фоне

Столкнулся с такой проблемойКак отследить нажатие клавиши в фоне

1273