Pull to refresh
16
Karma
0
Rating

Швея мотористка

Flutter vs Native: почему мы переходим с первого на второй

Google Killed

Так Android и Jetpack Compose, который упоминается в статье, тоже made by Google и по той же логике точно также могут быть закрыты. Можно, конечно, допустить, что неожиданно Flutter решат закрыть через какое-то время, но объективных причин для этого нет. Сам SDK развивается, количество вакансий и разработчиков растет, есть поддержка Fuchsia (если она когда-нибудь разовьётся во что-нибудь для мобилок).

Вот, например, давайте посмотрим на Dart: когда в него завезли null safety? Правильно, только весной 2021 года, а ведь это базовый механизм статической типизации.

Нет такого общепринятого понятия, как "базовый механизм статической типизации" для null safety. Просто в Kotlin/Swift это появилось уже после того, как вышел Dart. Да и сама фича достаточно сложная для добавления, потому что требует правки всей системы типов, миграции кода библиотек/приложений. Если сравнивать с Kotlin, то в итоге получилось даже лучше, потому что компилятор Dart может использовать информацию о типах и вырезать проверки на null в нативном коде, что повышает производительность и уменьшает размер сборки, а в Kotlin это все остается на границах публичных методов, потому что рантайм ничего не знает об этом. В Dart'e действительно нет многих фишек современных языков, но если смотреть не в моменте, а за период с релиза Flutter то развивается он достаточно бодро и разрабы прислушиваются к коммьюнити. Плюс у Dart'a тут есть возможность насобирать шишек за чужой счет и добавлять фичи более обдуманно. Да, конечно, хочется все и сразу, но развитие есть.

Конечно, прекрасно, что Flutter можно посмотреть в исходниках, как и увидеть, сколько issues сейчас открыто в официальном репозитории: их количество только растёт — это говорит о том, что команда пока не справляется с потоком ошибок. Например, только совсем недавно сделали, чтобы анимации не тормозили на iOS ¯_(ツ)_/¯

Количество isssues не равно количеству ошибок, потому что это могут быть фича реквесты, вопросы по использованию SDK, инфраструктурные проблемы, ошибки в desktop платформах (которые еще не в релизе), да и вообще что угодно. Количество тасок скорее говорит о том, что само сообщество вокруг Flutter большое и растет.

По поводу проблем с анимациями на iOS: такая проблема действительно была, но по статье не понятно, аффектило ли это вас или это просто пример. Когда мы выпускали приложение (которое уже было в сторе на Android) на iOS то таких проблем не было.

Собственный UI, характерный для обеих мобильных платформ

Поведение на разных платформах можно кастомизировать, часть из этого работает уже по умолчанию. В примерах есть приложение, которое на разных платформах выглядит нативно при этом максимально переиспользует общие части. Могут быть и другие варианты как это решить, все зависит от дизайна и требований. Тут действительно можно упрекнуть Flutter в том, что он не может как-то автоматически менять UI на разных платформах, чтобы приложение выглядело нативно, но UI паттерны могут отличаться слишком сильно.

В целом доводы в статье субъективные и эмоциональные, а при таком серьезом решении о миграции всего приложения на другой стек, выглядит как раз необдуманно, но, с другой стороны, дает понимание о подходах в компании к таким вопросам.

Первый байндинг для Exonum: почему мы выбрали Java

Интересно, а с точки зрения производительности JVM версия сильно потеряла?

Про рынок ИТ в России по-честному

По поводу Сбертеха. Не скажу за весь, но во многих проектах абсолютно такая же ситуация как описано в статье про «махровый авторитаризм». Новые технологии или идеи высмеиваются, люди которые их предлагают подвергаются натуральной травле в переписках, презентациях, чатах. Это не шутки. Про это тоже у автора было. Понятно, что технологии, ради технологий это не серьезно, особенно учитывая специфику банковских приложений. Но даже объективные факты в виде повышения качества и стабильности приложений не играют никакой роли.

Про рынок ИТ в России по-честному

А можно где-то узнать про цифры «библейского исхода» разработчиков? Откуда такая информация? Конкретных значений не нашёл в сети.

Kotlin и autoboxing

И?
В текущей ситуации, вам кажется что код выше, т.е.:
class BadDouble: Foo<kotlin.Double> {
    override fun bar(vararg a: kotlin.Double) {
        throw UnsupportedOperationException()
    }
}

Должен скомпилироваться в:
public final class BadDouble implements Foo<double>
{
  public void bar(double... a)
  {
    throw ((Throwable)new UnsupportedOperationException("not implemented"));
  }
}

Но такая конструкция в текущей версии Java просто не поддерживается, как это уже писал выше.
Какие есть варианты решения проблемы?
1. (как сейчас) выдавать ошибку компиляции
2. не явно преобразовывать Integer[] и вставлять хаки при конвертации между int[] и bar(vararg a: kotlin.Double).

Kotlin и autoboxing

kotlin.Double тоже не работает.

kotlin.Double? — выделил важное жирным
Но идея выкинуть дженерики из языка хорошая, мне нравится.

Не знаю откуда вы это взяли вообще.
А вообще таск открыт.

Читайте внимательней комментарий к таску, там как раз все развернуто описано.

Kotlin и autoboxing

Причем тут дизайн языка, да и vararg вообще, проблема как раз в самой платформе: в Java в принципе нельзя сделать метод с примитивом в качестве generic параметра, что вы и пытаетесь осуществить. Попробуйте переписать пример выше на обычной джаве и скормить там в качестве параметра типа обычный int — на текущей версии Java так сделать нельзя, почему это происходит кидал ссылку в статье про боксинг.

Так и Котлин не может kotlin.Double сконвертить в int для дженериков, поскольку сами дженерики и там и там практически идентичны. Да, он может это не пишет явно в сообщение об ошибке, но тут догадаться и так можно почему это происходит.

Чтобы исправить данный пример можно отметить в самом дженерике тип как kotlin.Double? тогда все будет успешно. Или просто убрать дженерики вообще и написать:
 fun bar(vararg a: Double) {
       throw UnsupportedOperationException("not implemented")
 }

тогда он сгенерит:
public final void bar(double... a) {
         throw (Throwable)(new UnsupportedOperationException("not implemented"));
      }

что вероятно и хотелось изначально.

Kotlin и autoboxing

Мне кажется достаточно трудно делать какие-то выводы об оптимизациях на уровне JVM в данном случае без отрыва от тестов. Вообще зачем действительно там nop мне трудно сказать, могу лишь предположить, что возможно это как-то связано с дебагом.

Kotlin и autoboxing

Естественно нет, он не будет за вас создавать синхронизацию и прочее. Для большинства случаев это просто не нужно, например если null переменная объявляется внутри метода.

Kotlin и autoboxing

if (name != null) {
   name.length()
}

Scala vs Kotlin (перевод)

inline все же в scala есть считай из «коробки», а вместо reified type есть TypeTag (если не путаю) с большим функционалом.

Все же разница там есть, если вы говорите про аннотацию inline, то мне кажется текущая версия комплятора скалы не сможет так развернуть лямбды, как это делает котлин, например, для всех функций работы с коллекциями. Если же речь о макросах, то тут у скалы возможности не ограничены, но использовать их сложней. reified type parameters связаны как раз именно с инлайном, поэтому у скалы вероятно тут прямого аналога нет, а TypeTag это вообще вроде как фича из рефлекшена, разве нет?

А так полностью согласен.

Scala vs Kotlin (перевод)

Вряд ли какая-то статья даст вам конкретный ответ на этот вопрос, пока сами не попробуете.

В сравнение со скалой, вероятно, переходить особого смысла и нет. Хотя если говорить еще про отличия и плюсы, то в статье не упомянули про инлайн функций и reified type parameters. На скале такое сделать значительно трудней. Очень радует маленький рантайм самого языка, особенно это удобно на андроиде, на скале с этим пока не так весело, но работы там вроде как ведутся. Еще в котлине заморочились c примитивами и их массивами, массивы также поддерживают все операции работы с коллекциями (map, find...), причем реализованы они не через ссылочные типы, т.е. боксинга/анбокисинга не будет, если конечно результат потом как-то не явно будет приведен к ссылочному типу, например, объявлен как nullable.

Из минусов:
— плагин для идеи периодически крашится, не критично, но хочется чтобы его довели до уровня;
— странный синтаксис в некоторых местах, например при объявлении свойств и если вдруг захочется добавить аннотацию к конструктору, то придется явно это указать;

Сбербанк делится опытом создания приложения в Material Design: стили и темы

Удаление шаблонов вроде есть, нужно сделать свайп справа на шаблоне.

AppCompat v21 — Material Design для пре-Lollipop устройств

Да это понятно, в любом случае его использовать. Просто «из коробки» не получается, жаль.

AppCompat v21 — Material Design для пре-Lollipop устройств

А можно как-то привести старые диалоги к новому внешнему виду с помощью AppCompat?

Как не потерять связь между фоновыми задачами и Activity

Ну да, в случае смены конфигурации лоадер тот же, а если все уходит в background то прибивается вместе с ui, если нужно чтобы такого не было то IntentService в помощь (ну или обычный сервис). Если же речь идет о запросах то тут volley классный врапер. В любом случае они используют статические переменные для хранения результата, так что чем-то похоже на вашу реализацию.

Как не потерять связь между фоновыми задачами и Activity

Не хочу с вами спорить, но судя по примеру вы не поняли как работают Loader'ы.

Как не потерять связь между фоновыми задачами и Activity

Ну и что? execute у AsyncBean тоже 2 раза нужно будет вызывать. С id проблему не вижу, ну есть он и есть, внутри отдельного фрагмента коллизия не возникнет :)
getLoaderManager().initLoader(0, ProgressLoader.buildArgs(1000) this);
getLoaderManager().initLoader(1, ProgressLoader.buildArgs(999), this);

или
YourAsyncTaskBean yourBean0 = new YourAsyncTaskBean(1000);
yourBean.execute(yourBeanListener);
YourAsyncTaskBean yourBean1= new YourAsyncTaskBean(999);
yourBean.execute(yourBeanListener);

разницы никакой, только в случае AsyncBean нужно еще обработать onSaveInstanceState/onPause/onResume, проверить savedInstanceState.

Как не потерять связь между фоновыми задачами и Activity

Кажется понял, для AsyncBean идентификаторы должны быть уникальны для всего приложения, поскольку они хранятся как статическое поле, а для лоадеров они уникальны только в пределах LoaderManager'a, который привязан к фрагменту или активити. Поэтому там все проще.

Как не потерять связь между фоновыми задачами и Activity

На счет Bundle'ов согласен с вами, действительно многобукоф, неудобно.
Не вижу в чем проблема с AsyncTaskLoader. Id будет хранится как обычная константа, этот идентификатор как раз определяет какая из задач сейчас выполняется. Сериализовывать тоже ничего не надо, зачем? Результат будет хранится в самом лоадере.
Честно говоря не понял зачем нужная такая сложная логика внутри UidGenerator для генерации айдишников AsyncBean. Но там кстати используются интерфейс Application.ActivityLifecycleCallbacks доступный только с 14 версии, а те же Loaders доступны в support-library v4.
1

Information

Rating
Does not participate
Registered
Activity