Android Broadcast
14.1K subscribers
3.41K photos
303 videos
11 files
5.72K links
Подборка новостей и статей для Android разработчиков.

Связь с автором @android_broadcast_bot
Реклама @android_broadcast_bot

РКН https://abdev.by/rkn_tg_ab
Download Telegram
#Gradle #Jetifier #AndroidX

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 для запуска таска - обязательно
#Kotlin

@JvmOverloads for Android Views

Подробный рассказ о том как для Kotlin функций и конструкторов с аргументами по умолчанию обеспечивать корректную работу на Android на пример собственных View и аннотации @JvmOverloads.
Если выполнить launch(Dispatchers.Main) на Main потоке, то в каком порядке будет выполнятсья ваш код?
Final Results
0%
Запуститься сразу
100%
Будет исполнен как освободиться Main поток
0%
Зависит от других условий
Правильный ответ - "Будет исполнен как освободиться Main поток"

Если выполнить код
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(), который возвращает true если выполнение должно продолжиться на другом потоке. Большинство CoroutineDispatcher возвращают true. Но для Dispatchers.Main потока будет эффективнее исполнять код сразу же если запуск корутины происходит с Main потока.

В API Coroutine вы можете найти интересный элемент Dispatchers.Main.immediate, который выполняет Coroutine мгновенно, когда она находится в том же контексте. Запустив код из предыдущего с Dispatchers.Main.immediate поста мы уже видим вывод: AB. Дилемма решена
#Kotlin #MemoryLeak

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, что оптимизирует их выполнение.
#JakeWharton #R8 #Optimizations

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 становится инструментом по умолчанию для оптимизации кода в ней.
#AndroidX #WorkManager

Android Jetpack WorkManager Stable Release

То чего так долго ждали свершилось WorkManager 1.0 Stable!

Ключевые функции WorkManager
👉 Возможность задания ограничений для выполнения задач, например необходимость выполнить когда есть подключение к сети и устройство заряжается
👉 Поддержка одноразовых и периодических задач
👉 Поддержка цепочек задач с входными и выходными данными
👉 Гарантирует выполнение задач, даже после перезагрузки устройства
👉 Поддержка Android 4.0+ (API 14+)
👉 Использует JobScheduler API на Android 6.0+ (API 23+) и комбинацию AlarmManager и BroadcastReceiver на более ранних версиях.
С чего начать использование?

1️⃣ Подключить зависимости

dependencies {
def work_version = 1.0.0

// Java
implementation
"android.arch.work:work-runtime:$work_version"

// Kotlin KTX + coroutines
implementation
"android.arch.work:work-runtime-ktx:$work_version"
}

2️⃣ Создать Worker, который будет выполнять задачу

class MyWorker(
ctx: Context,params: WorkerParameters
): Worker(ctx, params) {

override fun WorkerResult doWork() {
//do the work you want done in the background
return Result.success()
}
}  

3️⃣ Создайте Constraints для задачи (опционально)

val constraints: Constraints = Constraints.Builder()
.setRequiresCharging(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()

4️⃣ Создайте задачу

val myWork =
OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(constraints).build()

5️⃣ Добавьте ее на выполнение

WorkManager.getInstance().enqueue(myWork)
#Kotlin #KtAcademy

The beauty of Kotlin typing system от Marcin Moskala@Kt.Academy

Рассказ о прекрасно спроектированной системе типов в Kotlin, которая предоставляет удобный способ для работы с nullability, type inference и др.

В статье рассказывается о
👉 Тип Any? - супертип всех типов
👉 Тип Unit
👉 Тип Nothing - подтип всех типов
👉 Какой тип у null
Пример иерархии типов в Kotlin
#LibUpdate #JakeWharton

ThreeTebABP 1.2.0

Вышел новый релиз библиотеки ThreeTebABP, который добавил возможность загружать базу данных часовых поясов, расположенных в asset-ах
#Kotlin

When You Should Use Null in Kotlin

Является ли значение null проблемой и стоит ли избегать его использования? Например, я видел что разработчики используют пустые строки как значения переменных типа String, которые не проинициализированы.

К сожалению, репутация null испорчена системой типов в Java, частые NPE и множество if (value != null). null - это хороший выбор для представления состояния, когда у вас не проинициализрован объект, либо не доступен в текущий момент.

Для того чтобы ваше работы с null не приводила к ошибкам в Kotlin было сделано множество средств:
👉 система типов, различающая nullable и non-nullable типы
👉 безопасные вызовы ( ?. )
👉 безопасные приведения ( as? )
👉 else shorthand ( ?: )
👉 неизменяемые переменные

Язык должен помогать вам писать код как это логически правильно и не заставлять использовать что-то из-за своих ограничений. Kotlin старается соответствовать этим ожиданиям и у него это прекрасно получается!

Не бойтесь null, так в нем есть польза.
#AndroidLint #Performance #BestPractices #CodeQuality

Android Lint Performance Tips

Android Lint - это замечательный анализатор кода, который определяет специфичные для Android баги и потенциальные проблемы. Расстраивает его невысокая скорость работы, которая становиться хуже с каждым релизом 😪

Как ее увеличить читайте в статье из обсуждений о производительности Lint из Google Groups.

Замечание: Информации много и я не смог ее уместить в небольшой пост, поэтому чтобы не захламлять канал я вынес статью.
#GoogleMaps #GooglePlayServices #PlacesSDK

Introducing new, improved Places SDKs

Обновляется Google Maps Places SDK для Android. Что важного:
👉 Теперь API не привязано к Google Play Service и распространяется отдельным артефактом com.google.android.libraries.places:places:1.0.0
👉 Больше нет ограничения на количество запросов в день
👉 Более частные обновления и оперативное исправление багов
👉 Возможность получать новую информацию об местах: время работы, количество отзывов
👉 Доступ к plus codes - краткие коды, которые позволяют предоставить адрес для любого места на земле, даже в тех районах где традиционные адреса не существуют

Cтарое Places SDK будет закрыто 29 июля 2019
#Grow #EPAM

EPAM grow.by - Grow yourself and help others to grow with us

Я был приятно удивлен, когда пришел в компанию EPAM, насколько здесь качественно поставлен на поток процесс обучения сотрудников: тренинги, менторинг, митапы, поддержка участия в конференциях и пр.

Для организации процесса развития сотрудников существует закрытый портал, где человек видит свою текущую матрицу навыков и может поставить себе цели в развитие на новый уровень, либо вообще сменить направление разработки, например перейти из iOS в Android 😁.

Портал grow.by сделали открытым чтобы любой желающий мог посмотреть какие требования предъявляются для людей на различных уровнях и какие навыки вам надо подтянуть. Если же вы ментор, то вы можете при помощи портала выстроить программу менторинга для своих подопечных.
#AndroidX #ArchComponents #Lifecycle

Detecting when an Android app is in foreground or background

Как вы определяете что приложение ушло в фон или пользователь закрыл все Activity в приложение? В Android Architecture Components есть прекрасное решение для этого - ProcessLifecycleOwner.
#StrictMode #Library

StrictModeCompat

StrictMode в Android помогает находить различные проблемы в приложениях: выполнение I/O операций на главном потоке, незакрытые БД, неподходящие ресурсы и прочее.

Проблема в том, что это API очень фрагментировано и обновляется от версии к версии, и конфигурировать его для корректной работы на любой версии Android неудобно.

Для того чтобы эффективно использовать это API, я разработал библиотеку StrictModeCompat, которая позволяет не переживать есть ли API на текущей версии Android или нет - все что можно будет включить из того что вы захотели, будет включено.

Библиотека поддерживает Android 4.0+, Java 7 и имеет Kotlin DSL для удобной конфигурации.