Как стать автором
Обновить

Комментарии 27

НЛО прилетело и опубликовало эту надпись здесь

Нужно или дублировать объявление каждого виджета, или каждый раз проходить по всей иерархии вьюх в поисках нужного. Плюс неудобно когда объявление части вью находится в одном месте, а другая часть — в другом. Имхо, хорошо верстать на языке для вёрстки, если на нём действительно можно описать всю вёрстку.

В каком-то видео (вроде про Anko) говорили, что есть как минимум оверхед на парсинг xml. Попробую изучить вопрос
Еще какой оверхед, особенно при использовании MVP:
1) Мы пишем всю верстку на XML, прописывая тонны параметров, и еще и IDшники.
2) Потом мы в активити еще цепляем все это (и лучше через butter knife, а то уж больно много писать)
3) Потом мы пишем интерфейсы, которые будут управлять состоянием
4) Оверрайдим интерфейс в активити, где в методах уже пишем логику, которая будет изменять состояние объектов (буквы, цифры, возможности нажатия кнопок)
5) И, наконец, уже в презентаре мы будет вызывать методы интерфейса.

В 5 разных местах мы по чуть чуть пишем логику 1(!) экрана. Я с радостью выброшу хотя бы 1 пункт из списка, и вообще откажусь от XML.

Никто не говорит, что на Java нельзя написать DSLи. Можно и нужно, и эти DSL могут быть вполне годные с точки зрения декларативности и компактности, если не нужны будут арифметические операции. Но все равно выглядит это как костыль. Двойные скобочки, ._(); оператор new и не следование конвенции что имя класса должно быть с большой буквы, передача this в параметры — это мусор, от которого не удалось избавиться.


Конечно намного лучше, чем без DSL вообще. Но на anko это смотрится органично и изящно, там сам язык оптимизирован под такие DSL.

Вобщем-то на Java ввиду особенностей языка как раз нельзя написать нормальный DSL. Лямбды немного улучшают ситуацию, но не сильно. В частности, проблемы возникают с описанием иерархической структуры и со ссылками на проперти (которые всегда будут не type-safe). Стандартрый способ — клепать билдеры, но с ними получается очень гормоздко. Поэтому практически всегда для описания структур используют сторонний язык типа XML.


P.S. В Java 8 идентификатор _ объявлен как deprecated, а Java 9 вообще запрещает его использовать.

Ну вообще стандартный подход — код на Java, а верстку — на языке соответствующего шаблонизатора — XML лэйауты для андроида, Thymeleaf или Velocity для спринга и прочих вэб-приложений и так далее. Это удобно тем, что можно разделить код и представление, которые могут делать разные разработчики. Формировать лэйауты или вэб-страницы на Java возможно, но намного неудобнее.

Зачем тратить ресурсы и без того не очень мощных устройств на Android на такие операции, как inflate и findViewById

Можно так делать, а можно использовать databinding: https://stfalcon.com/ru/blog/post/faster-android-apps-with-databinding. Ну а то, что сам шаблон на XML, я не вижу в этом ничего такого фатального: большая часть рутинных операций верстки делается в визуальном редакторе той же студии, а непосредственно в коде лэйаута правится только уже какие-то небольшие вещи.
Язык поддерживает блоки кода без названия. Они выполняются по очереди сразу после конструктора.

Блок инициализации выполняется ДО каждого конструктора (а по факту копируется в него)


Как оказалось, возможностей Java хватает чтобы верстать декларативно.
Class {{
//blah blah
}}


Только вот DSL в Anko != созданию инстанса анонимного класса каждый раз при объявлении элемента в верстке. В итоге вместо того, чтобы тратить ресурсы и без того не очень мощных устройств на Android на такие операции, как inflate и findViewById, тратим ресурсы на загрузку 1000 и 1 анонимного класса в память.
Спасибо, поправил. После конструктора родителя и перед конструктором самого класса.
А по поводу производительности, хороший вопрос, что затратнее: загрузка анонимного класса или обращение к ресурсу, которое является I/O операцией. Я пробенчмаркаю, когда появится минутка.
А загрузка анонимных классов это не I/O операции?

Нет. Вся прогрузка подобных классов, связанная с IO, происходит при старте. Так что максимум возможных затрат — это jit компиляция.
Т.е. в случае XML у нас будет IO + парсинг + выполнение, в данном случае — у нас просто выполнение (ибо байткод изначально сделан для удобства работы JVM, а не для чтения человеком, как xml)

Я считаю что подгрузка кода и подгрузка разметки этим кодом происходит при первом обращении к этому классу.
Добавил бенчмарки. Дублирую ссылку. https://github.com/a-dminator/anko_benchmark
Громкий заголовок с бестолковым содержанием. Нет серьезно, неужели на хайпе котлина будут писаться и одобряться подобные статьи?
На тему декларативного фреймворка для описания Android-интерфейсов, посмотрите на Litho.
Спасибо, действительно лаконично выглядит

С инициализатором по-умолчанию есть очень большая проблема, связанная с контекстом. Дело в том, что полученный объект будет тянуть весь контекст класса, в котором он был вызван. Другими словами, в примере ниже если передать myvar куда-либо еще за пределы класса MyActivity, то он потащит всё активити с собой, что повлечёт неизбежную утечку памяти. При ревью я сразу делаю reject, видя такой код, поскольку дальнейшие часы на отлов утечек памяти, будет намного дороже.


class MyActivity extends Activity {
  private Class myvar = new Class {{ /* code */ }}
View, в любом случае, держит в себе контекст и ссылка на него даже не weak. Поэтому если передать View за пределы Activity, то это Activity неизбежно утечёт.

Согласен, хотя я больше про то, что люди любят так часто писать, инициализируя и другие классы.

Возьмите groovy, это уже стандарт как писать DSL на Java. Как пример, gradle на чистом groovy написан. Да у groovy побольше библиотека, но на нем можно и другие DSL сделать и он не заточен под одну задачу.
Что мне нравится в написании UI кодом — это всегда работающие code completion and navigation. Лямбды сильно улучшают компактность, но xml всё равно легче читается, хотя может дело в привычке.
Два момента. Первый момент: Google с Android Studio, как я понимаю, в сторону визуального создания интерфейсов (ConstraintLayout привет!). И идет оно туда (мы переходим ко второму моменту) для того что бы каждый занимался своим делом, дизайнеры рисовали интерфейсы а программисты реализовывали логику работы с ним. Это имхо.
писать перед каждым атрибутом «android:»


попробуйте посмотреть спецификацию xml Namespaces

Поддержу.
Вместо android: можно выбрать префикс покороче (например, a:), либо вообще установить пространством имён по умолчанию (тогда префиксы не понадобятся):


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ...>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" ...>
<LinearLayout xmlns="http://schemas.android.com/apk/res/android" ...>

С точки зрения XML — разницы никакой. Проблему с выражениями это, конечно же, не решает.

А еще в IDEA/Android Studio прекрасный автокомплит, и вместо android:layout_height можно просто написать lh и нажать Enter. Так что проблема очень-очень притянута за уши.
Хочется сахорка? Держи:
ui.frameLayout()
  .width(mathParent)
  .height(dip(100))
  .backgroundColor(RED)
  
  .child(x-> 
      x.frameLayout()
       .width(dip(50))
       .height(dip(50))
       .backgroundColor(GREEN)
       .gravity(CENTER)
   );

И пожалуйста, не делай кастомизацию класса при создании объекта для сахарка (это я про двойные фигурные скобки), особенно на андроиде.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации