Сегодня в выпуске: ответы Android engineering team на вопросы пользователей Reddit, запрет на доступ к сторонним приложениям в новых версиях Android, способ предотвратить клонирование приложения, множество советов, как писать чистый код на Kotlin, рассказ о функции with из уст разработчиков Koltin, польза и вред функций-расширений. А также: очередная порция библиотек и инструментов пентестера.
 

Почитать

 

Разработчики Android отвечают на вопросы

Android engineering team QA — ежегодная сессия вопросов и ответов команды разработчиков Android на Reddit. Как обычно, вопросы банальные, а ответы обтекаемые. Но есть несколько интересных моментов.

  1. С Android 11 производители будут обязаны сообщать пользователям, что их прошивка может убить приложение и не дать ему работать в фоне. Также в прошивке должна быть возможность отключить такое поведение. Кроме того, производителям придется убрать из своих прошивок белые списки популярных приложений, которые могут работать в фоне. В теории все это должно смягчить проблему некорректной работы приложений на китайских смартфонах.
  2. В Android 11 появился API, позволяющий узнать, почему приложение было завершено. Это опять же позволит выяснить, почему приложение на самом деле было завершено и связано ли это с некорректными действиями прошивки.
  3. В Android 11 появился сервис I/O Read Ahead Process (IORap), который выполняет предварительную загрузку нужных приложению ресурсов и данных во время старта приложения. Это дало прирост скорости холодного запуска в 5–20%.
  4. Еще один интересный API Android 11 — Data Access Auditing API, позволяющий получить информацию о том, какие приватные данные пользователя (местоположение, контакты и так далее) становятся доступны приложению. Это API для разработчиков, желающих выяснить, обращаются ли сторонние библиотеки или legacy-код к приватным данным пользователя. Подробности — в блоге Android Developers.
 

Запрет на доступ к приложениям

Package visibility in Android 11 — статья разработчиков Android о новом запрете Android 11, благодаря которому сторонние приложения больше не смогут получать информацию или запускать любое установленное на смартфон приложение.

Напомню, что до версии 11 Android предоставлял вполне официальный API для получения информации обо всех установленных на смартфон приложениях (имя, версия, время установки и так далее) и не налагал никаких запретов на запуск любых приложений. Этим пользовались не только сторонние менеджеры приложений, панели быстрого запуска и другой полезный софт, но и разного рода малварь и недобросовестные разработчики, сливающие информацию на третью сторону.

Начиная с Android 11 система будет ограничивать доступный приложению список установленных приложений и обяжет разработчиков перечислять приложения, с которыми приложение автора хочет контактировать, в манифесте:

<manifest package="com.example.game">
  <queries>
    <package android:name="com.example.store" />
    <package android:name="com.example.service" />
  </queries>
  ...
</manifest>

Кроме самих приложений, также можно перечислить типы интентов, которые собирается использовать приложение (в следующем примере приложение заявляет о своем намерении делиться изображениями с другими приложениями):

<manifest package="com.example.game">
  <queries>
    <intent>
      <action android:name="android.intent.action.SEND" />
      <data android:mimeType="image/jpeg" />
    </intent>
  </queries>
  ...
</manifest>

Эти требования будут распространяться на все приложения, собранные для API 30 и выше (targetSdkVersion=30), и не коснутся уже существующих приложений, до тех пор пока в Google Play не будет введен минимальный уровень API 30.

Для лаунчеров и других приложений, которым необходим доступ ко всем установленным приложениям, предусмотрено новое разрешение QUERY_ALL_PACKAGES. Но для его использования придется проходить ручную премодерацию.

 

Разработчику

 

Чистый код на Kotlin

Write fluent code in Kotlin — статья с советами о том, как сделать код на Kotlin более понятным для чтения.

1. Используй require и check

require(arg.length < 10) {
    "message"
}

val result = checkNotNull(bar(arg)) {
    "message"
}

/// вместо ///

if (arg.length < 10) {
    throw IllegalArgumentException("message")
}

val result = bar(arg)
    ?: throw IllegalStateException("message")

2. Используй функции вместо комментариев

val user = getUser(id)
validate(user)
activate(user)

private fun validate(user: User) { 
   // код валидации
}

private fun activate(user: User) { 
   // код активации
}

/// вместо ///

val user = getUser(id)

/*
 * Validate user
 */
// код валидации

/*
 * Activate user
 */
// код активации

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


2 комментария

  1. Аватар

    mitrofanzzz

    29.07.2020 в 09:26

    fun with(receiver: T, block: T.() -> R): R = receiver.block()
    Всматривался минут 10-15… потом заболела голова… понять что в этой строке происходит я так и не смог…

    • Аватар

      Countermeasure

      15.10.2020 в 18:16

      Функция with, принимающая в качестве аргумента объект reciever типа Т и функциональный тип block, являющийся extension к типу Т и возвращающий тип R. При этом вся функция with возвращает R, вызывая в своем теле extension block к объекту reciever.

Оставить мнение