image
Вчера в блоге Android была опубликована запись, в которой разработчики рассказывают о своей работе над уменьшением размера обновлений. Как отмечается в тексте, ежедневно миллионы пользователей обновляют свою систему и приложения, и многие из них внимательно следят за тем, сколько мобильного трафика на это уходит.

Для того, чтобы уменьшить размер обновлений, разработчики Android еще в июне 2016 года стали применять алгоритм bsdiff за авторством Колина Персиваля для патча бинарных файлов. Тогда это помогло снизить размер приложений и обновлений к ним, в среднем, на 47% относительно полного APK.

Теперь же команда Android хочет поделиться новым решением, которое позволяет снизить объем обновлений на, в среднем, 65% от первоначального размера. Речь идет о File-by-file patching.

Подход достаточно прост. Вместо того, чтобы скачивать полный APK и переустанавливать все файлы приложения, система обновления производит сверку пользовательских файлов и скачанных. Это позволяет загружать только те файлы, которые претерпели какие-либо изменения в ходе разработки.

По словам разработчиков Android этот простой, но эффективный подход позволяет сократить трафик обновлений на 6 петабайт ежедневно.

Но есть и некоторые подводные камни. Сжатие APK-файлов происходит почти так же, как и ZIP, с использованием Deflate. Это позволяет значительно уменьшить размер, но в тоже время затрудняет определение того, в какие именно файлы были внесены изменения:

image
Демонстрация работы Deflate

Как видно по изображению выше, внесение даже одного символа полностью изменяет структуру пережатого файла. Следовательно, file-by-file patching основывается на сравнении несжатых файлов между собой. В процессе обновления происходит сверка распакованных файлов, как старых, так и новых. На этом этапе все еще используется bsdiff. Затем, при применении патча выявляются файлы, требующие замены и скачиваются именно они. После этого APK опять пересобирается уже на стороне устройства. В качестве доказательств разработчики приводят сводную таблицу по ряду наиболее популярных приложений для Android:

image

Эти приложения уже используют систему обновления file-by-file.

У данного подхода есть несколько минусов. Первое — конечный APK должен полностью совпадать с исходным, байт в байт. На этот параметр влияет сборка Deflate (чаще всего используется собранная на основе Zlib) и ее настройки.

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

Другой минус подхода — требования к вычислительным мощностям на конечном устройстве, конкретно, к процессору. Процессы распаковки, сверки и обратной сборки в APK требуют значительных мощностей от устройства пользователя, и не все существующие девайсы смогут справиться с этой процедурой в равной степени успешно. Это приводит к более длительному применению патча на старых и маломощных устройствах. Кроме того, время обработки увеличивается пропорционально, исходя из размеров обновления.
Поделиться с друзьями
-->

Комментарии (38)


  1. Kenya-West
    07.12.2016 17:17
    +3

    Лечение всегда легче, чем профилактика, вот и придумывают костыли при обновлении, когда можно спроектировать ОС так, чтобы приложения на выходе получались с изначально небольшим размером. Почему нельзя разработать приложение весом в 3 МБ вместо 300 МБ? Ответ: сама ОС такая.

    Например, на Windows 10 приложения — это тупо набор скриптов, причём без преувеличения говорю. Даже обратная совместимость определяется двумя строчками в манифесте, все ресурсы хранит система, знай себе юзай ссылки на ресурсы, вызывай системные API и не пиши хуки, всё сделано за тебя, разрабатывай как хочешь. Итог: приложение на Android/iOS занимает 150 МБ, а на Windows — 1 МБ, и то это округление в большую сторону от 150 КБ.

    Вывод: 400 000 000+ юзеров на Windows 10 экономят трафика столько, сколько Android и не снилось!


    1. foxin
      07.12.2016 17:34

      Вывод: 400 000 000+ юзеров на Windows 10 экономят трафика столько, сколько Android и не снилось!

      Положим, что каждый юзер WinPhone получает 1 обновление в день (в среднем) и чистая экономия — 1 МБ. 4*10^8 юзеров * 10^6 Байт = 4*10^14 Байт = 400 ТБ.

      В то же время
      эффективный подход позволяет сократить трафик обновлений на 6 петабайт ежедневно
      .

      6 ПБ / 400 ТБ = 15 раз. Так что нет. Самая непопулярная платформа если даже и экономит трафик, то в 15 раз меньше, чем самая популярная. Так себе достижение, если честно.


      1. develop7
        08.12.2016 00:33
        +2

        Арифметика, бессердечная ты сука.


    1. ChiefPilot
      07.12.2016 18:01
      +2

      Может мобильная Windows всё-таки «взлетит» когда-нибудь? Просто народ пока не просёк (причём и программисты и пользователи).


      1. jehy
        08.12.2016 10:36
        +4

        Пишу под мобильную Windows и под Android. Пока что вся экосистема UWP просто враждебна разработчику. Если интересно — могу написать об этом целый отдельный пост боли и страданий.


        1. HUMAN1TY
          08.12.2016 10:52

          Конечно пишите, надо ведь поделиться опытом с теми, кто думает начать писать под эту платформу.


        1. ad1Dima
          08.12.2016 13:39

          Ну, боль и страдания есть на всех платформах. Причём чаще всего боль и страдания возникают тогда, когда принципы одной платформы пытаются перенести на другую.


        1. ChiefPilot
          08.12.2016 16:17

          Конечно интересно! Напишите, пожалуйста. И если так, то тогда понятно, почему так не популярна платформа. Жаль, конечно… Потому, что мне — как пользователю — почему-то очень нравится и интерфейс и то, что на 1 Гб ОЗУ всё бегает не хуже (а то и лучше), чем на двух-трёх на Андроиде.


          1. ad1Dima
            09.12.2016 11:46

            непопулярна она по 2 причинам: низкая доля WP. Неясные преимущества на ПК, перед традиционными средствами.

            Посмотрим, сможет ли Xbox и HoloLens стимулировать разработчиков.


    1. IgeNiaI
      07.12.2016 19:03

      Сильно сомневаюсь, что разработчики мобильной ОС думали о размере обновлений меньше, чем разработчики настольной ОС.
      В iOS и Android тоже используется принцип, когда все ресурсы и весь код совместимости старых приложений с новой системой есть в самой системе. Другой вопрос, когда новое приложение хотят запустить на старой системе, где нет нужного кода. Тогда приходится этот код встраивать в само приложение, и на Windows абсолютно такая же ситуация.
      Откуда тогда такой размер в приложениях? Это потому, что разработчики не хотят пользоваться стандартными ресурсами, и рисуют свои. Опять же, на Windows абсолютно такая же ситуация.


    1. lgorSL
      07.12.2016 19:17
      +4

      Почему нельзя разработать приложение весом в 3 МБ вместо 300 МБ? Ответ: сама ОС такая.

      Можно. На андроиде код занимает очень малую часть от приложения. Если повыкидывать из приложения звуки, кастомные кнопочки, сплеш-скрин и прочие красивости, оно будет весить очень мало. Только пользователи будут недовольны, потому что им красивостей хочется, а размер +- 10 мб не важен.


      Например, когда я писал небольшую игру на libgdx+scala, apk файл весил 3мб.
      Внутри лежит classes.dex на 1.7 мб (большая часть — scala library), ещё 4.6 мб занимают библиотечки от libgdx, всё это с остальными ресурсами ужимается в апк размером в 3мб. (единственный косяк — библиотечки лежат сразу для пяти платформ, "x86", "x86_64", "armeabi", "armeabi-v7a", "arm64-v8a")


      Итог: приложение на Android/iOS занимает 150 МБ, а на Windows — 1 МБ, и то это округление в большую сторону от 150 КБ.
      Вывод: 400 000 000+ юзеров на Windows 10 экономят трафика столько, сколько Android и не снилось!

      Ага, попробуйте поставить Windows Visual Studio. Даже если отключить все опции, она займёт 5 гб на диске. Для сравнения, образ линукса занимает около одного гигабайта. А в линуксе уже установлены gcc и прочие штуки для разработки.


      1. knotri
        08.12.2016 10:53
        +3

        (единственный косяк — библиотечки лежат сразу для пяти платформ, "x86", "x86_64", "armeabi", "armeabi-v7a", "arm64-v8a")


        Это можно пофиксить настойками в gradle, будут генерироваться отдельные apk для каждой платформы — плей маркет такое поддерживает — и сам разрулит какому пользователю что отдавать.


  1. Zapped
    07.12.2016 17:21
    +1

    После этого APK опять пересобирается уже на стороне устройства.

    и кто, интересно, его (APK) подписывает? ))


    1. foxin
      07.12.2016 17:27

      а в чем проблема, что будет собранный на самом девайсе APK подписан самим же девайсом?


      1. Zapped
        07.12.2016 17:30

        в целом, наверное, это не проблема
        непонятно только будет от кого апдейт прилетел (если эта информация вообще кому-нибудь нужна)


        1. foxin
          07.12.2016 17:36

          Апдейт будет прилетать от гугла и, как я понимаю, будет на лету подписываться гуглом же. Пришел апк — проверили что подписан гуглом — все ок.


          1. Zapped
            07.12.2016 17:42
            +2

            неее

            я понял почему

            конечный APK должен полностью совпадать с исходным, байт в байт

            в оригинале есть примечание:
            (see APK Signature Schema v2 for why).

            Схема подписи APK v2 — введена в Android 7.0. Встраивается в саму APK (ZIP-архив), в отличие от APK для Android 6.0 и ниже, где используется JAR-подпись (подробности по вышеприведённой ссылке)


            1. SadOcean
              08.12.2016 10:53
              +1

              Магазин будет присылать дельту и подпись (для полного файла).
              Дельта обновит распакованные ресурсы, их соберут в архив и проверят подпись.
              Точно так же в обычном случае присылают архив и подпись, проверяют подпись и ставят архив.
              Заморочки с сертификацией и доверием к открытому ключу разработчика в этом случае этой схемы не касаются, но там и так все решено.


              1. Zapped
                09.12.2016 18:12

                deleted


    1. Namolem
      09.12.2016 17:26

      а нельзя просто прикрепить новую подпись (ведь файлы то идентичны)?


      1. Zapped
        09.12.2016 18:06

        да новую-то можно
        только тут вопрос, который я озвучил: «кто подписал?», и соответственно, степени доверия к подписавшему )

        тут ведь вопрос в чём:
        подпись — это зашифрованный закрытым ключом подписавшего (в оригинале — разработчика) хэш содержимого
        если содержимое — изменилось хоть на байт — всё, подпись невалидна
        если подписал кто-то другой, то это «кто-то другой». нельзя удостоверить, что содержимое финального APK то же, что подписывал оригинальный разработчик

        c JAR-подписью такое могло бы сработать, т.к. там подписывается СОДЕРЖИМОЕ APK (который есть ZIP-архив)
        тут же речь о подписывании самого бинарного APK (APK Signature Schema v2). вот поэтому

        конечный APK должен полностью совпадать с исходным, байт в байт


      1. Zapped
        09.12.2016 18:20

        а не, не выйдет

        в Android нельзя поставить обновления, подписанные другим ключом, нежели обновляемое приложение. Можно только снести предыдущую версию и ставить «обновление» с нуля.


  1. Lucky_spirit
    07.12.2016 19:34

    Лично мне кажется, что появится новый вирус на Android, который заразит утилиту, занимающуюся сборкой APK файла на устройстве. Этот вирус будет просто потом инжектить вредоносный код в каждый собранный APK.


    1. ragequit
      07.12.2016 19:35

      Тогда будет несовпадение по размерам, если так со старта и на глаз.


    1. zagayevskiy
      07.12.2016 20:05

      Если всё так просто, то ничего не изменилось. Просто ваш мифический вирус уже сейчас заражает утилиту, занимающуюся установкой апк на устройстве.


    1. qw1
      08.12.2016 15:49

      Какой смысл заражать APK, собранные под конкретное устройство, если они с этого устройства никуда не уходят?

      Если хочется закрепиться в системе и, раз уж доступ на запись получен (обычно /system монтируется как read only при инициализации ядра), проще дописаться куда-нибудь к системным бинарникам.

      Например, во framework.jar, чтобы инжектиться автоматически в каждое приложение.


  1. rPman
    08.12.2016 00:18
    +1

    Такое ощущение что все комментаторы выше не хабравчане, а какие то левые

    Люди, ау! если каждое приложение будет таскать с собой полную копию используемого фреймворка, вместо того чтобы добавить его в зависимость, как это сделано в нормальных linux-системах, то тогда каждый фонарик будет весить 5-35мб вместо 10кб.

    Ради интереса, посмотрите, сколько приложений таскают с собой код webkit для просмотра html.
    впору уже аппаратную дедупликацию запускать, а во время установки, принудительно распаковывать все сжатые файлы, которые могут в принципе хранить дублируемый код, так как сделать все правильно никому уже не придет в голову…

    p.s. оперативная память например засирается именно этим.


    1. develop7
      08.12.2016 00:40
      -1

       Ради интереса, посмотрите, сколько приложений таскают с собой код webkit для просмотра html.

      Ух ты, как интересно. И сколько же?


      1. Areso
        08.12.2016 08:43

        К примеру, каждое приложение, написанное мной. На моем устройстве их больше одного)
        Они, правда, еще и ворох JS библиотек тащат, но по сравнению с webkit'ом — капля в море. 200 килобайт против 20 мегабайт.


        1. develop7
          08.12.2016 09:34

          И на Lollipop+ тоже?


          1. Areso
            08.12.2016 17:10

            У меня два устройства (4.4 и 4.2), не было возможности проверить 5 и новее. К тому же, я всегда старался включать как можно более старое API в проекте.


            1. develop7
              08.12.2016 17:37

              Ясно. Crosswalk пользуетесь?
              Я не просто так спросил про Lollipop, на 5+ поставляется обновляемый так же часто, как Google Chrome, Android System WebView, к-рый делает вот буквально то, что вы сказали. Как Crosswalk в shared mode, только всё официально и искаропки.


    1. qw1
      08.12.2016 16:03

      Что я вижу в apk, так это всякие SDK, как гугловские
      com.google.ads
      com.google.android.gms
      com.google.market
      ,
      которые нужны для in-app purchase,
      так и sdk от десятка социальных кнопок и рекламных сетей
      com.facebook.*
      com.flurry.*
      com.twitter.*
      com.yandex.metrica
      com.yandex.mobile.ads


      Ещё частый гость — библиотеки поддержки определённых визуальных стилей (разного рода action-bar-ы и контролы), которые с определённых версий есть в Android. Но нам же надо запуститься на как можно большем количестве платформ, и чтобы вёрстка не поплыла, поэтому системными не пользуемся.

      HTC-шные приложения содержат контролы типа com.htc.lib1.cc.view.viewpager, которые есть во framework, но для удобства, чтобы под каждое устройство не собирать свой пакет почтового клиента или календаря/будильника, их включают в обновления, скачиваемые из маркета. Поэтому будильник весит 5.5MB.


      1. zagayevskiy
        10.12.2016 13:47

        Android Support Library забыли упомянуть. Там с некоторых пор стали появляться вещи, которых во системе вообще нет (например, RecyclerView), а так же вещи, которые из системы использовать неудобно (например, фрагменты).


  1. DrGluck
    09.12.2016 10:01
    -1

    Это всё конечно благородно, но можно, вместо этого, будут выходить обновления на не самых старых телефонах, а? Например Galaxy Note 3/4, спасибо, пожалуйста.


    1. mekegi
      09.12.2016 10:34
      +1

      Товарищи из статьи отвечают за ядро андроида. Ваша претензия ни о чем, ибо обновления на ваш конкретный телефон зависят только от производителя этого вашего телефона.


      1. DrGluck
        09.12.2016 11:51

        Я понимаю, что это вопрос не к ним, это просто крик души. Каждый раз вижу в ленте новость об обновлении Андроида и каждый раз понимаю «мммкей, это не для тебя, жалкий неудачник».


        1. qw1
          09.12.2016 20:08

          Проще сказать себе «У меня нет на это времени».
          А так, при желании, можно себе любую версию залепить на любой девайс. А если не будет хватать памяти или ещё чего (например, нет поддержки определённых команд видеоускорения) — повод помозгоштурмить и сделать компромисное решение )))

          На HTC HD2, который выходил в 2009 на Windows Mobile 6.5, до сих пор то Windown Phone, то Android 7 выпустят. Даже отсутствие каких-то исходников этих людей не останавливает.