Какое ожидается поведение от этого кода?
Anonymous Quiz
44%
Приложение при запуске запросит разрешение на Bluetooth
12%
Приложение вылетит из-за receiver1
23%
Приложение вылетит из-за receiver2
21%
Код не скомпилируется
🔥5👍1
Как настроить автомиграцию в Room
В этой статье я расскажу про автомиграцию в Room (версия не ниже Room 2.4.0), варианты ее использования, преимущества, которые она дает, и проблемы, с которыми мы можем столкнуться.
Автомиграция поможет упростить процесс работы с базой данных, особенно если она большая, и в нее часто вносятся изменения. Она позволит не писать самостоятельно сложные SQL-запросы, а сгенерирует их автоматически в специально отведенной директории. Это позволит избежать опечаток при миграции и сэкономить время (если у нас запросы с огромным количеством полей).
Дисклеймер: в этой статье я буду ориентироваться на то, что мы уже умеем работать с Room и знаем, для чего нужна миграция. Материал будет полезен Android-разработчикам уровня Middle.
Читать статью
В этой статье я расскажу про автомиграцию в Room (версия не ниже Room 2.4.0), варианты ее использования, преимущества, которые она дает, и проблемы, с которыми мы можем столкнуться.
Автомиграция поможет упростить процесс работы с базой данных, особенно если она большая, и в нее часто вносятся изменения. Она позволит не писать самостоятельно сложные SQL-запросы, а сгенерирует их автоматически в специально отведенной директории. Это позволит избежать опечаток при миграции и сэкономить время (если у нас запросы с огромным количеством полей).
Дисклеймер: в этой статье я буду ориентироваться на то, что мы уже умеем работать с Room и знаем, для чего нужна миграция. Материал будет полезен Android-разработчикам уровня Middle.
Читать статью
Teletype
Как настроить автомиграцию в Room
Меня зовут Роман, я Android-разработчик в IT-компании SimbirSoft. В этой статье я расскажу про автомиграцию в Room (версия не ниже Room...
👍6❤🔥1
Activity: Что такое и как запустить?
Activity – основной компонент в андроиде. Активити – это экран, то что видит и с чем взаимодействует пользователь. Может содержать несколько View и фрагментов. Так же как и другие базовые компоненты, может быть точкой входа в приложение.
Активити с MAIN Intent Filter в манифесте запускается при старте приложения, когда пользователь кликает на иконку приложения.
Activity – основной компонент в андроиде. Активити – это экран, то что видит и с чем взаимодействует пользователь. Может содержать несколько View и фрагментов. Так же как и другие базовые компоненты, может быть точкой входа в приложение.
Активити с MAIN Intent Filter в манифесте запускается при старте приложения, когда пользователь кликает на иконку приложения.
👍7❤🔥1
Какое ожидается поведение от этого кода?
Считать, что timer - это TextView с соответствующим id.
Считать, что timer - это TextView с соответствующим id.
Anonymous Quiz
44%
Приложение исправно меняет у timer свойство text каждую секунду
9%
Приложение вылетит из-за 19 строки кода
41%
Приложение вылетит из-за 22 строки кода
6%
Приложение вылетит из-за 24 строки кода
👍6❤1
Нейронные сети и Android: как их создавать и использовать в мобильных приложениях
Тренд на нейросети не обошёл стороной и мобильные приложения. Многие фичи — например, распознавание изображений и речи, улучшение качество фото и видео — созданы с применением нейронных сетей.
Рассказываем про нейросети в Android-приложениях: какие есть инструменты для внедрения, как создавать свои модели и использовать готовые.
Читать статью
Тренд на нейросети не обошёл стороной и мобильные приложения. Многие фичи — например, распознавание изображений и речи, улучшение качество фото и видео — созданы с применением нейронных сетей.
Рассказываем про нейросети в Android-приложениях: какие есть инструменты для внедрения, как создавать свои модели и использовать готовые.
Читать статью
Teletype
Нейронные сети и Android: как их создавать и использовать в мобильных приложениях
Маски в Snapchat и Запрещёноgram, категоризация фотографий в галерее, улучшение качества фотографий в Google Camera — все эти фичи...
👍1
Activity: Жизненный цикл
Жизненный цикл активити состоит из шести основных коллбэков, вызываемых системой. В порядке вызова: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy().
onCreate() вызывается когда активити создается. В onCreate() вы должны вызвать метод setContentView().
onStart() вызывается когда активити отрисована и видима пользователю.
onResume() вызывается перед тем как активити станет доступна для взаимодействия с пользователем.
onPause() – метод симметричный onResume(). Пользователь больше не может взаимодействовать с активити, но активити частично видна пользователю. В этом состоянии UI активити может изменяться.
onStop() – метод симметричный onStart(). Вызывается, когда активити больше не видна пользователю.
onDestroy() – метод симметричный onCreate(). Вызывается перед тем, как активити будет уничтожена системой.
Несколько примеров:
1. Пользователь жмет Home. В этом случае активити больше не видна, поэтому вызываются onPause(), onStop(). Пользователь открывает приложение снова - onStart(), onResume().
2. Пользователь переходит на другую активити внутри приложения (реализуется вызовом startActivity()) – onPause(), onStop(). Пользователь возвращается на предыдущую активити – onStart(), onResume().
3. Вызов finish() – onPause(), onStop(), onDestroy(). Когда пользователь перейдет на эту активити снова, она будет создана с нуля без сохранения состояния.
4. Пользователь поворачивает телефон и ориентация активити меняется. Активити пересоздается и вызываются коллбеки onPause(), onStop(), onDestroy(), onCreate(), onStart(), onResume() с сохранением состояния.
Это базовые методы активити. Более подробно они описаны в документации.
В полный жизненный цикл также входят onRestart(), onSaveInstanceState(), onRestoreInstanceState(), onNewIntent() и другие методы, которые разберем в будущем.
Жизненный цикл активити состоит из шести основных коллбэков, вызываемых системой. В порядке вызова: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy().
onCreate() вызывается когда активити создается. В onCreate() вы должны вызвать метод setContentView().
onStart() вызывается когда активити отрисована и видима пользователю.
onResume() вызывается перед тем как активити станет доступна для взаимодействия с пользователем.
onPause() – метод симметричный onResume(). Пользователь больше не может взаимодействовать с активити, но активити частично видна пользователю. В этом состоянии UI активити может изменяться.
onStop() – метод симметричный onStart(). Вызывается, когда активити больше не видна пользователю.
onDestroy() – метод симметричный onCreate(). Вызывается перед тем, как активити будет уничтожена системой.
Несколько примеров:
1. Пользователь жмет Home. В этом случае активити больше не видна, поэтому вызываются onPause(), onStop(). Пользователь открывает приложение снова - onStart(), onResume().
2. Пользователь переходит на другую активити внутри приложения (реализуется вызовом startActivity()) – onPause(), onStop(). Пользователь возвращается на предыдущую активити – onStart(), onResume().
3. Вызов finish() – onPause(), onStop(), onDestroy(). Когда пользователь перейдет на эту активити снова, она будет создана с нуля без сохранения состояния.
4. Пользователь поворачивает телефон и ориентация активити меняется. Активити пересоздается и вызываются коллбеки onPause(), onStop(), onDestroy(), onCreate(), onStart(), onResume() с сохранением состояния.
Это базовые методы активити. Более подробно они описаны в документации.
В полный жизненный цикл также входят onRestart(), onSaveInstanceState(), onRestoreInstanceState(), onNewIntent() и другие методы, которые разберем в будущем.
👍15
Что произойдёт после поворота экрана?
Anonymous Quiz
24%
На экране ничего не изменится.
18%
TextView очистится, а EditText - нет.
21%
EditText очистится, а TextView - нет.
38%
Оба элемента очистятся.
👍9👨💻6
Activity: Как пережить поворот экрана?
При повороте экрана активити уничтожается и создается заново. Вызываются коллбэки onPause(), onStop(), onSaveInstanceState(), onDestroy() – onCreate(), onStart(), onRestoreInstanceState(), onResume().
Чтобы сохранить состояние активити, вы должны переопределить метод onSaveInstanceState() и положить данные в Bundle.
При реинициализации активити, Bundle с сохраненным состоянием передается в onCreate() и в onRestoreInstanceState().
Система вызывает onSaveInstanceState() и onRestoreInstanceState() только в том случае, когда необходимо сохранить состояние, например при повороте экрана или при убийстве активити для освобождения памяти. Данные коллбэки не вызываются, если пользователь выходит из активити нажав Back или если активити убивается вызовом finish().
onSaveInstanceState() вызывается после onStop() на версии API ≥ 28. На API < 28 этот коллбэк вызывается перед onStop() и нет гарантий до или после onPause().
onRestoreInstanceState() вызывается после onStart().
При повороте экрана активити уничтожается и создается заново. Вызываются коллбэки onPause(), onStop(), onSaveInstanceState(), onDestroy() – onCreate(), onStart(), onRestoreInstanceState(), onResume().
Чтобы сохранить состояние активити, вы должны переопределить метод onSaveInstanceState() и положить данные в Bundle.
При реинициализации активити, Bundle с сохраненным состоянием передается в onCreate() и в onRestoreInstanceState().
Система вызывает onSaveInstanceState() и onRestoreInstanceState() только в том случае, когда необходимо сохранить состояние, например при повороте экрана или при убийстве активити для освобождения памяти. Данные коллбэки не вызываются, если пользователь выходит из активити нажав Back или если активити убивается вызовом finish().
onSaveInstanceState() вызывается после onStop() на версии API ≥ 28. На API < 28 этот коллбэк вызывается перед onStop() и нет гарантий до или после onPause().
onRestoreInstanceState() вызывается после onStart().
👍8🔥2
Нужно ли думать о сохранении состояния, если приложение поддерживает только портретную ориентацию?
– Да.
Поворот экрана – это частный случай Configuration Changes. Другой пример – изменение языка системы.
Кроме того, как было упомянуто постом выше, система может уничтожить активити, чтобы использовать занятые ей ресурсы. В этом случае состояние сохраняется и восстанавливается при пересоздании активити.
– Да.
Поворот экрана – это частный случай Configuration Changes. Другой пример – изменение языка системы.
Кроме того, как было упомянуто постом выше, система может уничтожить активити, чтобы использовать занятые ей ресурсы. В этом случае состояние сохраняется и восстанавливается при пересоздании активити.
👍5
Fragment
Fragment используется для отображения части UI на экране. Фрагмент создается внутри активити или внутри другого фрагмента.
Для создания и управления фрагментами используется FragmentManager.
Класс-наследник класса Fragment должен иметь дефолтный конструктор без параметров. Система использует этот конструктор при пересоздании фрагмента.
Начиная с API v28 системный класс Fragment – deprecated. Рекомендуется использовать Fragment из Support Library.
Fragment используется для отображения части UI на экране. Фрагмент создается внутри активити или внутри другого фрагмента.
Для создания и управления фрагментами используется FragmentManager.
Класс-наследник класса Fragment должен иметь дефолтный конструктор без параметров. Система использует этот конструктор при пересоздании фрагмента.
Начиная с API v28 системный класс Fragment – deprecated. Рекомендуется использовать Fragment из Support Library.
👍1
Расскажите про способы добавления и переключения фрагментов. Как работать с бэкстэком?
Для управления фрагментами используются два класса: FragmentManager и FragmentTransaction.
Для получения FragmentManager используются метод активити getSupportFragmentManager() или метод фрагмента getChildFragmentManager().
FragmentManager начинает транзакцию и возвращает объект FragmentTransaction вызовом метода beginTransaction().
Методы класса FragmentTransaction, которые необходимо знать - add(), remove() и replace().
add() добавляет фрагмент на активити или другой фрагмент. Принимает аргументами containerViewId, в который добавляется фрагмент, инстанс фрагмента, тег.
Другой способ добавить фрагмент - определить в лэйауте с помощью тега <fragment>.
remove() - операция, обратная add(). Удаляет фрагмент.
replace() удаляет все фрагменты, добавленные методом add() в заданный контейнер, и добавляет переданный аргументом фрагмент в контейнер. Параметр tag может быть null.
Эти операции не выполняются сразу же после вызова методов. Метод commit() завершает транзакцию и выполняет операции транзакции.
Метод addToBackStack() добавляет транзакцию в Back Stack. Это значит, что когда пользователь нажмет Back транзакция откатится. addToBackStack() применяется ко всем операциям в транзакции. Например следующий код добавляет транзакцию из трех операций в бэкстэк:
Для управления фрагментами используются два класса: FragmentManager и FragmentTransaction.
Для получения FragmentManager используются метод активити getSupportFragmentManager() или метод фрагмента getChildFragmentManager().
FragmentManager начинает транзакцию и возвращает объект FragmentTransaction вызовом метода beginTransaction().
Методы класса FragmentTransaction, которые необходимо знать - add(), remove() и replace().
add() добавляет фрагмент на активити или другой фрагмент. Принимает аргументами containerViewId, в который добавляется фрагмент, инстанс фрагмента, тег.
Другой способ добавить фрагмент - определить в лэйауте с помощью тега <fragment>.
remove() - операция, обратная add(). Удаляет фрагмент.
replace() удаляет все фрагменты, добавленные методом add() в заданный контейнер, и добавляет переданный аргументом фрагмент в контейнер. Параметр tag может быть null.
Эти операции не выполняются сразу же после вызова методов. Метод commit() завершает транзакцию и выполняет операции транзакции.
Метод addToBackStack() добавляет транзакцию в Back Stack. Это значит, что когда пользователь нажмет Back транзакция откатится. addToBackStack() применяется ко всем операциям в транзакции. Например следующий код добавляет транзакцию из трех операций в бэкстэк:
fragmentTransactionМетод popBackStack() удаляет транзакцию с верхушки бэкстэка, возвращает true, если бэкстэк хранил хотя бы одну транзакцию.
.add(R.id.fragmentContainer1, fragment1)
.add(R.id.fragmentContainer2, fragment2)
.replace(R.id.fragmentContainer1, fragment3)
.addToBackStack("tag")
.commit()
👍2
Важен ли порядок, в котором добавляются операции в FragmentTransaction?
Документация описывает два случая, в которых порядок важен:
1. Метод commit() должен вызываться последним.
2. Если несколько фрагментов добавляются в один контейнер, то порядок добавления определяет порядок в котором фрагменты отрисовываются в иерархии view.
Есть еще третий случай. Если метод addToBackStack(String name) вызывается несколько раз на одной транзакции, то транзакция добавляется в бэкстэк один раз с тегом, который передается в последнем вызове метода.
Пример:
Поведение нескольких addToBackStack() не задокументировано и может различаться на разных версиях ОС, так что не забудьте на собеседовании сказать, что вы бы так никогда делать не стали.
Документация описывает два случая, в которых порядок важен:
1. Метод commit() должен вызываться последним.
2. Если несколько фрагментов добавляются в один контейнер, то порядок добавления определяет порядок в котором фрагменты отрисовываются в иерархии view.
Есть еще третий случай. Если метод addToBackStack(String name) вызывается несколько раз на одной транзакции, то транзакция добавляется в бэкстэк один раз с тегом, который передается в последнем вызове метода.
Пример:
supportFragmentManager.beginTransaction()Создается одна транзакция с тегом add2, которая добавляет сразу два фрагмента. При нажатии кнопки Back оба фрагмента будут удалены.
.add(R.id.fragmentContainer, Fragment1())
.addToBackStack("add1")
.add(R.id.fragmentContainer, Fragment2())
.addToBackStack("add2")
.commit()
Поведение нескольких addToBackStack() не задокументировано и может различаться на разных версиях ОС, так что не забудьте на собеседовании сказать, что вы бы так никогда делать не стали.
👍6
Когда вызывается метод onUserLeaveHint?
Anonymous Quiz
25%
Когда пользователь нажимает на кнопку "Домой"
35%
Когда пользователь выходит из приложения с помощью кнопки "Назад"
31%
Когда Activity прерывается, например, звонком
9%
Когда Activity крашится, за исключением ошибки "Приложение не отвечает"
👍7
Своя библиотека под Android за один вечер
В процессе написания статьи она незаметно для меня трансформировалась из туториала по публикации Android-проекта как библиотеки в максимально душную статью о том, как математика пригодилась разработчику с гуманитарным бэкграундом в отрисовке анимашек. Статью подробную, разжеванную, с множеством строк кода. Возможно, не для слабонервных.
Читать статью
В процессе написания статьи она незаметно для меня трансформировалась из туториала по публикации Android-проекта как библиотеки в максимально душную статью о том, как математика пригодилась разработчику с гуманитарным бэкграундом в отрисовке анимашек. Статью подробную, разжеванную, с множеством строк кода. Возможно, не для слабонервных.
Читать статью
Teletype
Своя библиотека под Android за один вечер
В процессе написания статьи она незаметно для меня трансформировалась из туториала по публикации Android-проекта как библиотеки...
👍4⚡2👨💻1
Чем отличается tag в методах add() и addToBackStack()?
Tag в методе add() присваивается фрагменту. Fragment.getTag() возвращает этот тег.
Тег фрагмента используется в методе findFragmentByTag().
Tag в методе addToBackStack() это на самом деле не tag, а name. Имя транзакции, которое присваивается объекту BackStackEntry и возвращается методом getName().
Этот вопрос возник на собеседованиях, потому что когда только появились фрагменты было популярно писать такой код:
Удобно? Нет! Не надо так делать.
Tag в методе add() присваивается фрагменту. Fragment.getTag() возвращает этот тег.
Тег фрагмента используется в методе findFragmentByTag().
Tag в методе addToBackStack() это на самом деле не tag, а name. Имя транзакции, которое присваивается объекту BackStackEntry и возвращается методом getName().
Этот вопрос возник на собеседованиях, потому что когда только появились фрагменты было популярно писать такой код:
val tag = "home_fragment"Сначала добавляется фрагмент с одинаковым тегом фрагмента и именем транзакции. Потом, используя имя-тег, можно получить инстанс фрагмента по позиции в бэкстэке.
supportFragmentManager.beginTransaction()
.add(R.id.fragmentContainer, HomeFragment, tag)
.addToBackStack(tag)
.commit();
…
val lastEntryIndex = supportFragmentManager.backStackEntryCount - 1
val tag = supportFragmentManager.getBackStackEntryAt(lastEntryIndex).name
val topFragment = supportFragmentManager.findFragmentByTag(tag)
Удобно? Нет! Не надо так делать.
👍7❤1
Метод FragmentManager.commit() – синхронный или нет?
– Асинхронный.
Это значит, что транзакция не выполняется во время вызова метода. commit() добавляет транзакцию в очередь главного потока и транзакция выполняется при первой возможности.
Чтобы выполнить транзакцию синхронно, можно воспользоваться методом commitNow() вместо commit() или вызвать executePendingTransactions() после метода commit().
– Асинхронный.
Это значит, что транзакция не выполняется во время вызова метода. commit() добавляет транзакцию в очередь главного потока и транзакция выполняется при первой возможности.
Чтобы выполнить транзакцию синхронно, можно воспользоваться методом commitNow() вместо commit() или вызвать executePendingTransactions() после метода commit().
👍12
Электронные книги? Аудиокниги? Смешать, но не взбалтывать
Отпуск - замечательное время, которое не занято работой, а значит можно и нужно заняться тем, чем давно хотелось - хобби. Сегодня поговорим об одной из любимых тем - читалка и все, что с ней связано.
Читать статью
Отпуск - замечательное время, которое не занято работой, а значит можно и нужно заняться тем, чем давно хотелось - хобби. Сегодня поговорим об одной из любимых тем - читалка и все, что с ней связано.
Читать статью
Teletype
Электронные книги? Аудиокниги? Смешать, но не взбалтывать
Всем привет!
👍4