#CodeQuality #Facebook #MachineLearning
Facebook Infer is a static analysis tool base on machine learning
Facebook открыла доступ к инструменту статического анализа кода, который использует алгоритмы на основе машинного обучения и позволяет анализировать код, самообучаясь и обнаруживать массу проблем, которые простым статическим анализатором неподвластны.
Описание принципов работу Infer
Попробуйте Infer онлайн
Facebook Infer is a static analysis tool base on machine learning
Facebook открыла доступ к инструменту статического анализа кода, который использует алгоритмы на основе машинного обучения и позволяет анализировать код, самообучаясь и обнаруживать массу проблем, которые простым статическим анализатором неподвластны.
Описание принципов работу Infer
Попробуйте Infer онлайн
Fbinfer
Infer Static Analyzer | Infer | Infer
A tool to detect bugs in Java and C/C++/Objective-C code before it ships
#GooglePlay
Expanding target API level requirements in 2019
Google вновь поднимает target sdk для всех приложений в Google Play. Теперь минимальная версия будет Android 9.0 (API 28) для всех приложений:
❗С августа - для всех новых
❗С ноября - для всех обновляемых
Также пользователи будут получать предупреждение при установке приложений, о том что оно не адаптировано под новые версии Android. Работать это будет по следующим правилам:
❗С августа новые приложения будут получат предупреждения если target sdk < 26 (Android 8.0)
❗С ноября новые версии существующих приложений получат предупреждения если target sdk < 26
Если версия Android вашего устройства меньше обязательной target sdk, то предупреждения вы не увидите. Каждый год минимальная target sdk будет повышаться до следующей мажорной версии ОС.
Как вы относитесь к таким изменениям?
Expanding target API level requirements in 2019
Google вновь поднимает target sdk для всех приложений в Google Play. Теперь минимальная версия будет Android 9.0 (API 28) для всех приложений:
❗С августа - для всех новых
❗С ноября - для всех обновляемых
Также пользователи будут получать предупреждение при установке приложений, о том что оно не адаптировано под новые версии Android. Работать это будет по следующим правилам:
❗С августа новые приложения будут получат предупреждения если target sdk < 26 (Android 8.0)
❗С ноября новые версии существующих приложений получат предупреждения если target sdk < 26
Если версия Android вашего устройства меньше обязательной target sdk, то предупреждения вы не увидите. Каждый год минимальная target sdk будет повышаться до следующей мажорной версии ОС.
Как вы относитесь к таким изменениям?
Android Developers Blog
Expanding target API level requirements in 2019
In a previous blog we described how API behavior changes advance the security and privacy protections of Android, and include user experience improvements that prevent apps from accidentally overusing resources like battery and memory.
Since November 2018…
Since November 2018…
#AndroidStudio #Marble #ApplyChanges
Android Studio Project Marble: Apply Changes
Google наконец-то прислушалась к мольбам Android разработчиков о улучшение Android Studio в плане стабильности, фикса багов и чрезмерного потребления ресурсов. результат этого - Project Marble, в рамках которого на протяжение релизов Android Studio 3.4 и дальше будет происходить работы над стабилизацией.
Первая статья в серии описывает падение Instant Run и замену его на Apply Changes, доступный в Android Studio 3.5. необходимость нового механизма возникла в том что Instant Run не справлялась со сложными приложениями.
Отличия в Apply Changes следующие:
👉 Минимальная поддерживаемая версия Android 8.0 Oreo
👉 Apply Changes не модифицирует APK во время сборки, а опирается на механизмы в Android 8.0, которые позволяют переопределять классы "на лету"
👉 Оптимизация механизма сравнения установленного и нового APK для вычисления разницы
Android Studio Project Marble: Apply Changes
Google наконец-то прислушалась к мольбам Android разработчиков о улучшение Android Studio в плане стабильности, фикса багов и чрезмерного потребления ресурсов. результат этого - Project Marble, в рамках которого на протяжение релизов Android Studio 3.4 и дальше будет происходить работы над стабилизацией.
Первая статья в серии описывает падение Instant Run и замену его на Apply Changes, доступный в Android Studio 3.5. необходимость нового механизма возникла в том что Instant Run не справлялась со сложными приложениями.
Отличия в Apply Changes следующие:
👉 Минимальная поддерживаемая версия Android 8.0 Oreo
👉 Apply Changes не модифицирует APK во время сборки, а опирается на механизмы в Android 8.0, которые позволяют переопределять классы "на лету"
👉 Оптимизация механизма сравнения установленного и нового APK для вычисления разницы
Medium
Android Studio Project Marble: Apply Changes
A deep dive into how the Android Studio team built Apply Changes, the successor to Instant Run.
#Assembler #Hardcore
Как мы писали Android-приложение на ассемблере
Какой язык выбрать чтобы написать "Hello World!" на Android. Обычный программист напишет на Java, хипстер на Kotlin, но самые серьезные, сторонники подхода Чака Норриса выберут ассемблер. Автор статьи из суровых и решил повторить это за Чаком! Больше подробностей о том как это сделать вы найдете по ссылке.
Как мы писали Android-приложение на ассемблере
Какой язык выбрать чтобы написать "Hello World!" на Android. Обычный программист напишет на Java, хипстер на Kotlin, но самые серьезные, сторонники подхода Чака Норриса выберут ассемблер. Автор статьи из суровых и решил повторить это за Чаком! Больше подробностей о том как это сделать вы найдете по ссылке.
Tproger
Как мы писали Android-приложение на ассемблере
Статья на Tproger — Как мы писали Android-приложение на ассемблере
Какую архитектуру использует ваше приложение?
Final Results
36%
MVP
40%
MVVM
5%
MVI
11%
Нет архитектуры
8%
Прочее
#Conference #Mobius
Mobius Piter 2019
22-23 мая в Санкт-Петербурге пройдет конференция Mobius в рамках которой вы сможете послушать доклады от спикеров из крупнейших компаний.
Но самое главное для меня - я выступлю с докладом о лучших практиках в корутинах: как не допустить ошибок при их использование на Android, и как писать код таким образом. что корутины дали максимальную эффективность! Буду рад увидеть вас в зале 😁
Скидка на билет по промокоду 10% AndroidBroadcastPromo
Mobius Piter 2019
22-23 мая в Санкт-Петербурге пройдет конференция Mobius в рамках которой вы сможете послушать доклады от спикеров из крупнейших компаний.
Но самое главное для меня - я выступлю с докладом о лучших практиках в корутинах: как не допустить ошибок при их использование на Android, и как писать код таким образом. что корутины дали максимальную эффективность! Буду рад увидеть вас в зале 😁
Скидка на билет по промокоду 10% AndroidBroadcastPromo
Mobius 2025 Autumn. Конференция по мобильной разработке
Mobius 2025 Autumn | Конференция по мобильной разработке
Mobius 2025 Autumn. Единственная в России профильная IT-конференция для разработчиков мобильных приложений. Android, iOS, Flutter, Kotlin Multiplatform, кроссплатформенная разработка — в десятках докладов, воркшопов и дискуссий.
Скидка на билеты Mobius Piter 2019 по промокоду AndroidBroadcastPromo - 10%🔥
Mobius 2025 Autumn. Конференция по мобильной разработке
Mobius 2025 Autumn | Конференция по мобильной разработке
Mobius 2025 Autumn. Единственная в России профильная IT-конференция для разработчиков мобильных приложений. Android, iOS, Flutter, Kotlin Multiplatform, кроссплатформенная разработка — в десятках докладов, воркшопов и дискуссий.
Большинство современных проектов используют RxJava либо Kotlin Coroutines.
Знаете ли вы разницу между Schedulers.computations() и Schedulers.io()? Между Dispatchers.Default и Dispatchers.IO? Чур документацией не пользоваться!
Знаете ли вы разницу между Schedulers.computations() и Schedulers.io()? Между Dispatchers.Default и Dispatchers.IO? Чур документацией не пользоваться!
Final Results
52%
Да
39%
Нет
9%
Не пользуюсь Rx и корутинами
#Rx #Coroutines #Concurrency
Understanding CPU- and I/O-bound for asynchronous operations
В современных приложениях мы выносим обработку долгих операций на фоновые потоки. Знаете ли Вы какие операции надо запускать на этих пулах потоков, а самое главное почему? Почему не использовать единый пул для всех фоновых операций? Зачем в Kotlin Coroutines и RxJava есть понятия I/O-bound и CPU-bound.
Причиной этому является как I/O операции ведут себя по сравнению к CPU интенсивным операция. Чтение данных из файлов, потоков, сокетов или сети часто содержит много ожидания: подключение к источнику, дождаться ответа и только потом идет его реальная передача, которая может также приостанавливаться из-за низкой скорости или загруженности. Операции не связанные с чтение не из оперативной памяти вызывают IOwait - системный вызов, который сообщает процессору о необходимости приостановить выполнение текущего потока, пока данные станут доступны или будут успешно переданы.
Важно помнить, что потоки, выполняющие I/O операции, проводят значительную часть времени в ожидании. При маленьком пуле потоков, выделенных для таких операций у вас может быть простой приложения.
С другой стороны, если рассмотреть операции которые интенсивно используют CPU, например процессинг изображений, тяжелые расчеты и пр., то для таких операций нет блокирующих событий как IOwait и потоки приостанавливаются только на основе механизма распределения ресурсов в ОС.
Подведя итоги описанной выше разницы работы задача с IO и CPU можно понять что:
👉 CPU и I/O операции стоит выполнять в разных пулах потоков
👉 пул для CPU интенсивных операций должен опираться на количество ядер в устройстве и не превышать его
👉 пул для I/O операций может быть довольно большим
Рассмотрим пример:
1️⃣ Скачаем картинку из сети
2️⃣ Сделаем ей blur
3️⃣ Отобразим ее на устройстве
Мы имеем 3 разных пула, которы надо использовать:
1️⃣ I/O
2️⃣ CPU
3️⃣ Main
Реализация примера на корутинах:
Реализация на RxJava:
В дополнение можно сказать что Coroutine выигрывают еще в том что они не блокируют потоки и позволяют во время ожидания выполняться на них других операциям, что позволяет более эффективно использовать пулл I/O.
Understanding CPU- and I/O-bound for asynchronous operations
В современных приложениях мы выносим обработку долгих операций на фоновые потоки. Знаете ли Вы какие операции надо запускать на этих пулах потоков, а самое главное почему? Почему не использовать единый пул для всех фоновых операций? Зачем в Kotlin Coroutines и RxJava есть понятия I/O-bound и CPU-bound.
Причиной этому является как I/O операции ведут себя по сравнению к CPU интенсивным операция. Чтение данных из файлов, потоков, сокетов или сети часто содержит много ожидания: подключение к источнику, дождаться ответа и только потом идет его реальная передача, которая может также приостанавливаться из-за низкой скорости или загруженности. Операции не связанные с чтение не из оперативной памяти вызывают IOwait - системный вызов, который сообщает процессору о необходимости приостановить выполнение текущего потока, пока данные станут доступны или будут успешно переданы.
Важно помнить, что потоки, выполняющие I/O операции, проводят значительную часть времени в ожидании. При маленьком пуле потоков, выделенных для таких операций у вас может быть простой приложения.
С другой стороны, если рассмотреть операции которые интенсивно используют CPU, например процессинг изображений, тяжелые расчеты и пр., то для таких операций нет блокирующих событий как IOwait и потоки приостанавливаются только на основе механизма распределения ресурсов в ОС.
Подведя итоги описанной выше разницы работы задача с IO и CPU можно понять что:
👉 CPU и I/O операции стоит выполнять в разных пулах потоков
👉 пул для CPU интенсивных операций должен опираться на количество ядер в устройстве и не превышать его
👉 пул для I/O операций может быть довольно большим
Рассмотрим пример:
1️⃣ Скачаем картинку из сети
2️⃣ Сделаем ей blur
3️⃣ Отобразим ее на устройстве
Мы имеем 3 разных пула, которы надо использовать:
1️⃣ I/O
2️⃣ CPU
3️⃣ Main
Реализация примера на корутинах:
launch(Dispatchers.IO) {
val image = api.fetchImageAsync(url).await()
val blurred =withContext(Dispatchers.Default) {
image.blur()
}
withContext(Dispatchers.Main) {
displayImage(blurred)
}
}
Реализация на RxJava:
api.fetchImageObservable(url)
.subscribeOn(Schedulers.io()
.observeOn(Schedulers.computation())
.map { blurImageSync(it) }
.observeOn(AndroidSchedulers.mainThread())
.subscribe { displayImage(it) }
В дополнение можно сказать что Coroutine выигрывают еще в том что они не блокируют потоки и позволяют во время ожидания выполняться на них других операциям, что позволяет более эффективно использовать пулл I/O.
#Gradle #Jetifier #AndroidX
can-i-drop-jetifier Gradle Plugin
Вы уже перешли в своем проекте с Android Support Library (ASL) на AndroidX? Но вот в чем загвоздка - не все авторы библиотек сделали тоже самое, поэтому вам в код тянутся зависимости ASL.
Решить эту проблему призвана утилита Jetifier от Google. Она превращает старый ASL код в новый AndroidX, но на такую модификацию байткода требуется время. Но если в вашем проекте уже нет ASL библиотек. то лучше отключить Jetifier.
Плагин позволяет определить какие из библиотек используют ASL Просто выполните:
Отключение Jetifier для запуска таска - обязательно
can-i-drop-jetifier Gradle Plugin
Вы уже перешли в своем проекте с Android Support Library (ASL) на AndroidX? Но вот в чем загвоздка - не все авторы библиотек сделали тоже самое, поэтому вам в код тянутся зависимости ASL.
Решить эту проблему призвана утилита Jetifier от Google. Она превращает старый ASL код в новый AndroidX, но на такую модификацию байткода требуется время. Но если в вашем проекте уже нет ASL библиотек. то лучше отключить Jetifier.
Плагин позволяет определить какие из библиотек используют ASL Просто выполните:
./gradlew -Pandroid.enableJetifier=false canIDropJetifier
Отключение Jetifier для запуска таска - обязательно
GitHub
GitHub - plnice/can-i-drop-jetifier: Gradle plugin that checks if there are dependencies using support library instead of AndroidX.
Gradle plugin that checks if there are dependencies using support library instead of AndroidX. - GitHub - plnice/can-i-drop-jetifier: Gradle plugin that checks if there are dependencies using suppo...
#Kotlin
@JvmOverloads for Android Views
Подробный рассказ о том как для Kotlin функций и конструкторов с аргументами по умолчанию обеспечивать корректную работу на Android на пример собственных View и аннотации
@JvmOverloads for Android Views
Подробный рассказ о том как для Kotlin функций и конструкторов с аргументами по умолчанию обеспечивать корректную работу на Android на пример собственных View и аннотации
@JvmOverloads
.zsmb.co
@JvmOverloads for Android Views
The @JvmOverloads annotation is a convenience feature in Kotlin for interoperating with Java code, but there is one specific use case on Android where it shouldn’t be used carelessly.
Если выполнить launch(Dispatchers.Main) на Main потоке, то в каком порядке будет выполнятсья ваш код?
Final Results
0%
Запуститься сразу
100%
Будет исполнен как освободиться Main поток
0%
Зависит от других условий
Правильный ответ - "Будет исполнен как освободиться Main поток"
Если выполнить код
В логах вы увидите: BA
Если выполнить код
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState
launch(Dispatchers.Main) {
log("A")
}
log("B")
}
В логах вы увидите: BA
#Kotlin #Coroutines
Launching a Kotlin Coroutine for immediate execution on the Main thread
Как можно сделать так, чтобы при запуске корутины на текущем потоке происходил ее мгновенный запуск? CoroutineDispatcher отвечает за поток, который будет выполнять код внутри корутины, есть метод isDispatchNeeded(), который возвращает
В API Coroutine вы можете найти интересный элемент Dispatchers.Main.immediate, который выполняет Coroutine мгновенно, когда она находится в том же контексте. Запустив код из предыдущего с Dispatchers.Main.immediate поста мы уже видим вывод: AB. Дилемма решена
Launching a Kotlin Coroutine for immediate execution on the Main thread
Как можно сделать так, чтобы при запуске корутины на текущем потоке происходил ее мгновенный запуск? CoroutineDispatcher отвечает за поток, который будет выполнять код внутри корутины, есть метод isDispatchNeeded(), который возвращает
true
если выполнение должно продолжиться на другом потоке. Большинство CoroutineDispatcher
возвращают true
. Но для Dispatchers.Main потока будет эффективнее исполнять код сразу же если запуск корутины происходит с Main потока.В API Coroutine вы можете найти интересный элемент Dispatchers.Main.immediate, который выполняет Coroutine мгновенно, когда она находится в том же контексте. Запустив код из предыдущего с Dispatchers.Main.immediate поста мы уже видим вывод: AB. Дилемма решена
Medium
Launching a Kotlin Coroutine for immediate execution on the Main thread
If you launch a coroutine using launch(Dispatchers.Main) while already on the main thread, will the code execute immediately?
#Kotlin #MemoryLeak
How Kotlin helps you avoid memory leaks
Kotlin ввел множество новых механизмов, которые упрощают написание кода в Android:
👉 null safety
👉 type inference
👉 закрытые от наследования классы по умолчанию
👉 все вложенные классы по умолчанию статические
Но в дополнение ко всем ещё Kotlin может помогать вам избегать утечек памяти.
Такой код не вызовет утечки в Android, хотя его аналог в Java бы вызывал.
Разница заключается в том, что лямбда в Kotlin интерпретируется как статический вложенный класс, и не хранит ссылку на внешний класс, если код внутри не обращается к внешним нестатическим элементам. В Java независимо от каких-либо условий всегда будет создаваться обычный класс.
Замечание: вышеприведенное рассматривается для Java 7, так как Android разработка сейчас использует эту версию в байт коде. Для Java 8 лямбды исполняются с помощью invokedynamic, что оптимизирует их выполнение.
How Kotlin helps you avoid memory leaks
Kotlin ввел множество новых механизмов, которые упрощают написание кода в Android:
👉 null safety
👉 type inference
👉 закрытые от наследования классы по умолчанию
👉 все вложенные классы по умолчанию статические
Но в дополнение ко всем ещё Kotlin может помогать вам избегать утечек памяти.
class SampleActivity : Activity() {
override fun onCreate(savedState: Bundle?) {
super.onCreate(savedState)
setContentView(R.layout.activity_leak)
button.setOnClickListener {
startAsyncWork()
}
}
private fun startAsyncWork() {
val work = Runnable {
SystemClock.sleep(20000)
}
Thread(work).start()
}
}
Такой код не вызовет утечки в Android, хотя его аналог в Java бы вызывал.
Разница заключается в том, что лямбда в Kotlin интерпретируется как статический вложенный класс, и не хранит ссылку на внешний класс, если код внутри не обращается к внешним нестатическим элементам. В Java независимо от каких-либо условий всегда будет создаваться обычный класс.
Замечание: вышеприведенное рассматривается для Java 7, так как Android разработка сейчас использует эту версию в байт коде. Для Java 8 лямбды исполняются с помощью invokedynamic, что оптимизирует их выполнение.
Medium
How Kotlin helps you avoid memory leaks
Does Kotlin help you avoid memory leaks? In this article I’m analyzing the bytecode generated when using lambdas to see if that’s true.
#JakeWharton #R8 #Optimizations
R8 Optimization: Class Constant Operations
Продолжение серии статей о оптимизация кода, которые реализованы в R8 от Jake Wharton. В новой статье рассказывается о оптимизации констант классов.
Рассмотрим частый пример классов в константах:
Такие константы очень часто используются для логирования. Если рассмотреть после компиляции кода, то
R8 получила такую оптимизацию кода и теперь неважно как вы будете создать
Android Studio 3.4 уже на подходе и R8 становится инструментом по умолчанию для оптимизации кода в ней.
R8 Optimization: Class Constant Operations
Продолжение серии статей о оптимизация кода, которые реализованы в R8 от Jake Wharton. В новой статье рассказывается о оптимизации констант классов.
Рассмотрим частый пример классов в константах:
private static final String TAG = "MyClass";
// or
private static final String TAG =
MyClass.class.getSimpleName();
Такие константы очень часто используются для логирования. Если рассмотреть после компиляции кода, то
MyClass.class.getSimpleName()
всегда будет возвращать одно и тоже значение - "MyClass"
. Фактически в оптимизированном байткоде можно делать подмену выполнения метода на простую строку. Важно понимать что это не работает для случая getClass().getSimpleName()
, т.е. когда класс получается динамически.R8 получила такую оптимизацию кода и теперь неважно как вы будете создать
LOG_TAG
для ваших логов 🎉Android Studio 3.4 уже на подходе и R8 становится инструментом по умолчанию для оптимизации кода в ней.
Jake Wharton
R8 Optimization: Class Constant Operations – Jake Wharton