Как стать автором
Обновить
6
0
Найденов Юрий @EBCEu4

Пользователь

Отправить сообщение
Вот появился Kotlin, теперь пишу под Android. Единственное, что у MS получилось сделать нормально это C#, но сделать его open-source и отвязать от Windows, догадались они слишком поздно.
Программирует же кто — то…
Все, к чему прикасается Microsoft, превращается в тыкву, это говорит вам убежденный дотнетчик с восьми летним опытом, из них 4 на windows phone.
Ну, на мой взгляд, он просто лучше. Если вы переживаете насколько он production ready в его защиту могу сказать — половина андройд студии написана на нем, a в 3 версии gradle будет его использовать в качестве скриптового языка вместо groovy.
Что касается rx, Java 8 и retro справляются ровно до тех пор пока вы используете стандартные операторы rx — сказывается отсутствие extension методов. Если вы хотите покинуть rx парадигму или наоборот в нее перейти, также возникают проблемы.

Пока все хорошо:
observable.map(x->x.getProp()).distinct();

Но, если нам нужны свои кастомные операторы:
ObservableOperators.anotherOperator(ObservableOperators.custom(observable.map(x->x.getProp()).distinct()), 10)

Вместо:
observable.map(x->x.getProp()).distinct().custom().anotherOperator(10);

На самом деле это далеко не все. Чего стоят inline лямбды не напрягающие GC. И много чего еще…
Основная мысль, которую я пытаюсь донести, android — frontend разработка, текущая тенденция — тонкий, легкий клиент. Мы не пишем супернагруженные суперпараллельные вундеркластеры, так почему бы не писать наш тонкий (как правило) клиент лаконично и красиво.

Нужно стараться делать все вызовы pure.
Оператор map модифицирующий внешний контекст или захватывающий textView неприемлем.
Если где — то кроме subscribe есть closure, значит, что-то пошло не так, нужно пересматривать решение.

Зачем .flatMap(Observable::from)? Ради того, чтобы взять 7 первых ссылок?
queryTitle должен принимать список url и возвращать список title и не нужен будет flatMap, не нужно будет проверять на null.

Вы отсеиваете уже проделанную работу queryTitle, на которую было потрачено процессорное время,
если вы хотите брать 7 первых ссылок то надо фильтровать их на входе, или передавать ограничение в качестве параметра queryTitle.

subscribeOn и observeOn лучше оставить на усмотрение вызывающей стороне, так она сможет решить сама где она хочет производить парсинг, а где обновление UI.
В крайнем случае subscribeOn можно вызвать внутри реализации api, если ваш контракт подразумевает только асинхронное выполнение.

Что — то вроде того:
queryURLs(url)
       .map(this::queryTitle)
       .subscribeOn(Schedulers.io())
       .observeOn(AndroidSchedulers.mainThread())
       .subscribe(titles -> textView.setText(Joiner.on("\n\n").join(titles));


У вас же, queryURLs делает работу на background потоке и потом пушит результат в ui, а следом queryTitle опять начинает выполнять загрузку и парсинг в своем background потоке.
Это приводит к ненужным пушам в looper ui потока, которому и так есть чем заняться.
Поэтому лучше оставлять такие решения вызывающей стороне.

Надеюсь не очень скомкано получилось.
Как же нелепо выглядит rx на джаве 7.
На джаве 8 или с retrolambda, rx начинает выглядеть нелепо, когда нужно добавить свой кастомный оператор.
Когда android разработчики начнут использовать Kotlin?
Вы слишком близко к мозгу все воспринимаете. Маркетологи просто взяли популярную рейверскую мем фразу, переиначили, получилось «прикольно». Я думаю тут таких подтекстов не нужно искать.
Автор выпилил старое видео. Новое тут.
Достаточно доходчиво объясняют.
Строковые ресурсы (StringResources.Online) собираются из XML файла аналогичным способом в класс имена свойств которого идентичны ключам из XML, и вы их используете в коде. Слой для хранения настроек Application Settings также использует генерацию класса с обертками над строковыми идентификаторами, чтобы обеспечить вам строготипизированное хранилище без магических строк. В конце-концов, Visual studio генерирует вам поле в классе window\page на каждый именованный контрол. Это мешало модульности? Расширяемости? Это придумал не я, это придумали в Microsoft.
Вы упорно доказываете мне, что топором дырку сверлить неудобно.
«Правильной» архитектуры не бывает, бывают задачи и инструменты для их решения, архитектура это тоже инструмент. Вы вырываете мои слова из контекста, я не говорю, что это «нужно», я привел пример того как используют ресурсы создатели данной технологии.
Ресурсы для Вас это почему — то обязательно кисти или конвертеры? В ресурсах можно хранить любые application scope вещи, которые хочется удобно использовать через StaticResource. Даже в шаблоне проекта под Windows Phone 8+ LocalizedResources объявлены в Application.Resources для удобного использования через {Binding}. Можно сколь угодно долго спорить об архитектурных аспектах, о том, что кто — то использовал бы в данном случае DI и т.д.

Определенно Вы неправильно меня поняли, моя статья не призывает заменить {Binding} и не призывает использовать все без исключения ресурсы из кода. В статье описан подход, который упростит именно те случаи, когда это необходимо, я дал инструмент, каждому инструменту свое место применения. Когда Вам нужно просверлить отверстие, вы берете дрель, когда Вам нужно наколоть дрова, вы берете топор. Вы же говорите, что топором неправильно сверлить отверстия, я согласен — неправильно.

Ваш пример с вытягиванием переименованного ресурса не очень подходит, т.к. в этом случае и оригинальный {Binding} также перестанет работать.
В случае с проектом, над которым я сейчас работаю, такое решение удобно, когда в проекте есть несколько глобальных настроек, которые не меняются, например:
  • основной цвет
  • класс с командами навигации
  • класс с командами, которые должны быть доступны на любом экране (например logout)


В случае с командами это удобно, т.к. я могу либо использовать StaticResource во View, либо вызвать команду из Code-Behind.

Вы всегда можете передать такие настройки и через DependencyProperty, но зачем?

Резюмирую: полезно использовать для всего глобального скоупа, который может использоваться в Code-Behind, чтобы не плодить для каждого такого свойства DependencyProperty и использовать Binding, т.к в этом случае это просто лишний код.
Первая проблема — мы не можем загрузить второй instance класса Application, при вызове:
XamlReader.Load(File.OpenRead(Host.ResolvePath("/App.xaml")));

выдается исключение:
System.InvalidOperationException: Cannot create more than one System.Windows.Application instance in the same AppDomain

Изначально у меня была идея вообще не парсить xaml, а выковырять все из Application.Current, но я не смог найти подходящего решения.
Плюс такой подход не решает второй проблемы — ресурсы могут быть объявлены не только у корневого элемента, они могут быть и у Grid, который объявлен как дочерний элемент страницы, и у Custom элемента из сторонней библиотеки.
Мне показалось, что xpath справляется с задачей найти ресурсы на любом уровне вложенности вполне гибко.

Подход с загрузкой через XamlReader годится для разбора отдельныx файлов c ресурсами, корневым элементом которых является ResourceDictionary.
Вы имеете в виду XamlReader? С ним получается вообще трехколесный с reflection.
По второму пункту согласен. Спасибо за совет.
Комментарий удален.
На мой взгляд XAML хорош тем, что в нем объявление ресурсов выглядит гармонично.
Тут получается зеркальная ситуация — мы объявляем ресурсы в коде и ссылаемся на них из XAML.
К сожалению, расширение разметки x:Static доступно только в WPF.

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность