AStA: собираем APK на самом устройстве

    Что такое AStA? Это акроним от «Android Studio on Android». Это метод, позволяющий собирать проекты Android Studio на Android устройстве с помощью chroot/Debian, JDK, Android SDK и Gradle.

    Зачем это вообще нужно? Да мало ли, зачем… Бывает, например, хочется проверить какую-то идею, а декстопа под рукой нет. В общем, пусть на вопрос «зачем» каждый ответит для себя сам.

    Какие существуют альтернативы? Из существующих решений мне известно только AIDE, но у него есть свои минусы. Во-первых, постоянно выскакивает окошко с предложением проапгрейдить версию за 600 рублей, а если этого не сделать, то нельзя сохранять проекты, состоящие из более чем 5 файлов. Во-вторых, AIDE не поддерживает сборку проектов Android Studio, состоящих из более, чем одного модуля.

    Что нам потребуется?


    1. Устройство с ядром Android, совместимым с Debian Stretch.
    2. Наличие root-прав на устройстве.
    3. 4 ГБ свободного места на карте памяти под образ Debian.
    4. Заранее установленный на устройстве Busybox.
    5. Desktop с Debian на борту + adb (в случае установки через скрипт).

    Установка через скрипт


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

    #!/bin/sh
    # Чтобы не спрашивало пароль в середине скрипта:
    sudo echo 'installDebianOnAndroid script started'
    # Архитектура устройства
    ARCH=armhf
    # Версия Debian
    DEBIAN_VERSION=stretch
    # Путь к карте памяти на устройстве:
    STORAGE=/sdcard
    # Место, где мы создадим образ на декстопе:
    DATA_DRIVE=/Data
    # Для совместимости с файловой системой FAT32 
    # размер файла образа не должен превышать (2^32 - 1) байт
    BS=1M
    COUNT=4095
    # Создаем файл образа:
    dd if=/dev/zero of=$DATA_DRIVE/debianOnAndroid.img bs=$BS count=$COUNT
    # Создаем точку монтирования на десктопе:
    mkdir -p ~/debianOnAndroid
    # Создаем на образе файловую систему:
    sudo mkfs.ext3 $DATA_DRIVE/debianOnAndroid.img
    # Монтируем образ:
    sudo mount -o user,loop,exec,dev $DATA_DRIVE/debianOnAndroid.img ~/debianOnAndroid/
    # С помощью debootstrap создаем на образе debian:
    sudo debootstrap --verbose --arch $ARCH --foreign $DEBIAN_VERSION ~/debianOnAndroid/ http://ftp.se.debian.org/debian
    # Размонтируем образ:
    sudo umount $DATA_DRIVE/debianOnAndroid.img
    # Кладем образ на карту памяти:
    adb push $DATA_DRIVE/debianOnAndroid.img $STORAGE
    # Busybox лучше заранее установить через приложение:
    # https://play.google.com/store/apps/details?id=stericson.busybox
    #adb push busybox/busybox-armv6l /sdcard/busybox
    #adb shell su -c cp /sdcard/busybox /data/local/busybox
    #adb shell su -c chmod 755 /data/local/busybox
    # Создаем папки AStA на Android:
    adb shell mkdir -p $STORAGE/AStA
    adb shell mkdir -p $STORAGE/AStA/Projects
    adb shell mkdir -p $STORAGE/AStA/archives
    adb shell mkdir -p $STORAGE/AStA/scripts
    # Скрипт для первого монтирования и настройки Debian
    adb push firstMountAndConfigureDebian.sh $STORAGE/AStA/scripts
    # Скрипты для монтирования и размонтирования
    adb push mountDebian.sh $STORAGE/AStA/scripts
    adb push umountDebian.sh $STORAGE/AStA/scripts
    # Заранее приготовленные архивы JDK, Android SDK и gradle
    ANDROID_SDK_TAR_GZ=android-sdk-linux.tar.gz 
    JDK_8_TAR_GZ=jdk-8u144-linux-arm32-vfp-hflt.tar.gz
    GRADLE_ZIP=gradle-3.5-bin.zip
    # Кладем архивы в папку AStA/archives на карте памяти:
    adb push archives/$ANDROID_SDK_TAR_GZ $STORAGE/AStA/archives
    adb push archives/$JDK_8_TAR_GZ $STORAGE/AStA/archives
    adb push archives/$GRADLE_ZIP $STORAGE/AStA/archives
    # Скрипт для запуска команд Gradle:
    adb push gradleExec.sh $STORAGE/AStA/scripts
    # Запускаем скрипт первоначальной настройки Debian:
    adb shell su -c sh $STORAGE/AStA/scripts/firstMountAndConfigureDebian.sh
    # Размонтируем образ:
    adb shell su -c sh $STORAGE/AStA/scripts/umountDebian.sh
    # Имя файла приложения:
    ASTA_APP_APK=AStA-app.apk 
    # Кладем приложение в папку AStA и устанавливаем:
    adb push apk/$ASTA_APP_APK $STORAGE/AStA
    echo 'installing AStA-app'
    adb shell pm install -r $STORAGE/AStA/$ASTA_APP_APK
    echo 'installDebianOnAndroid script done'
    

    Скрипт настройки Debian на устройстве:

    echo 'firstMountAndConfigureDebian script started'
    # Пароль для доступа по SSH:
    PASSWORD=1234567
    # Точка монтирования Debian:
    MNTPT=/data/local/debianOnAndroid
    # Путь к карте памяти:
    STORAGE=/sdcard
    # Образ Debian:
    IMG_FILE=$STORAGE/debianOnAndroid.img
    # Версия Debian:
    DEBIAN_VERSION=stretch
    # Создаем точку монтирования:
    mkdir -p $MNTPT
    # Монтируем образ:
    busybox mount -o loop $IMG_FILE $MNTPT
    # Нужно для корректной работы chroot:
    export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:/system/xbin:/su/bin:/su/xbin
    # Второй этап debootstrap:
    chroot $MNTPT /debootstrap/debootstrap --second-stage
    # Настраиваем apt:
    echo "deb http://ftp.se.debian.org/debian $DEBIAN_VERSION main contrib non-free" > $MNTPT/etc/apt/sources.list
    # Монтируем:
    busybox mount -t proc none $MNTPT/proc
    busybox mount -t sysfs none $MNTPT/sys
    busybox mount -o bind /dev $MNTPT/dev
    busybox mount -t devpts none $MNTPT/dev/pts
    export TMPDIR=/tmp
    #chroot $MNTPT /bin/bash
    # Чтобы apt мог работать с сетью, нужно перевести его в группу Internet (3003)
    chroot $MNTPT sed -i 's#_apt:x:104:65534::/nonexistent:/bin/false#_apt:x:104:3003::/nonexistent:/bin/false#' /etc/passwd
    # Устанавливаем пакеты, которые нам понадобятся:
    chroot $MNTPT apt-get update
    chroot $MNTPT apt-get --yes upgrade
    chroot $MNTPT apt-get --yes install ne openssh-server unzip \
     android-sdk-build-tools android-sdk-platform-tools
    # Устанавливаем пароль для доступа по SSH:
    echo "echo 'root:$PASSWORD' | chpasswd" > $MNTPT/root/setpasswd.sh
    chroot $MNTPT /bin/sh /root/setpasswd.sh
    cat $MNTPT/root/setpasswd.sh
    # Заменяем строчку в конфиге SSH, чтобы работал доступ под root'ом:
    chroot $MNTPT sed -i '/PermitRootLogin without-password/c\PermitRootLogin yes' /etc/ssh/sshd_config 
    chroot $MNTPT /etc/init.d/ssh restart
    # Создаем папку AStA в Debian и монтируем на нее папку Android:
    mkdir -p $MNTPT/AStA
    busybox mount -o bind $STORAGE/AStA $MNTPT/AStA
    # Имена файлов архивов:
    ANDROID_SDK_TAR_GZ=android-sdk-linux.tar.gz
    JDK_8_TAR_GZ=jdk-8u144-linux-arm32-vfp-hflt.tar.gz
    GRADLE_ZIP=gradle-3.5-bin.zip
    # Распаковываем архивы:
    chroot $MNTPT tar -xzvf /AStA/archives/$ANDROID_SDK_TAR_GZ -C /opt 
    chroot $MNTPT tar -xzvf /AStA/archives/$JDK_8_TAR_GZ -C /opt
    chroot $MNTPT unzip /AStA/archives/$GRADLE_ZIP -d /opt
    #
    echo 'firstMountAndConfigureDebian script done'
    

    Запуск установки через скрипт


    Чтобы установить на устройство образ Debian, приложение и все необходимые скрипты, нужно выполнить следующую последовательность действий:

    git clone https://github.com/tabatsky/AStA.git
    cd AStA/scripts
    # Подправить переменные в скрипте start.sh
    sh start.sh
    

    Так же можно скачать готовый образ Debian (под armhf) здесь, либо скачать через приложение.

    Подключение и отключение Debian


    Следующий скрипт монтирует Debian и запускает ssh, а также монтирует папку AStA с устройства на Debian:

    MNTPT=/data/local/debianOnAndroid
    STORAGE=/sdcard
    IMG_FILE=$STORAGE/debianOnAndroid.img
    mkdir -p $MNTPT
    busybox mount -o loop $IMG_FILE $MNTPT
    export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:/system/xbin:/su/bin:/su/xbin
    busybox mount -t proc none $MNTPT/proc
    busybox mount -t sysfs none $MNTPT/sys
    busybox mount -o bind /dev $MNTPT/dev
    busybox mount -t devpts none $MNTPT/dev/pts
    export TMPDIR=/tmp
    #chroot $MNTPT bash
    chroot $MNTPT /etc/init.d/ssh start
    mkdir -p $STORAGE/AStA
    mkdir -p $MNTPT/AStA
    busybox mount -o bind $STORAGE/AStA $MNTPT/AStA
    

    А этот, соответственно, останавливает ssh и все размонтирует:

    MNTPT=/data/local/debianOnAndroid
    export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/system/bin:/system/xbin:/su/bin:/su/xbin
    busybox umount $MNTPT/AStA
    chroot $MNTPT /etc/init.d/ssh stop
    busybox umount $MNTPT/dev/pts
    busybox umount $MNTPT/dev
    busybox umount $MNTPT/proc
    busybox umount $MNTPT/sys
    busybox umount $MNTPT
    

    Запустить данные скрипты можно через shell:

    su -c sh /sdcard/AStA/scripts/mountDebian.sh  
    su -c sh /sdcard/AStA/scripts/umountDebian.sh  
    

    Либо можно просто нажать на соответствующую кнопку в приложении.

    Запуск команд Gradle


    Запустить сборку Gradle можно, подключившись по ssh, и запустив следующую команду:

     sh /AStA/scripts/gradleExec.sh /AStA/Projects/MyProject/myModule/ myCmd
    # Например:
     sh /AStA/scripts/gradleExec.sh /AStA/Projects/AStA-app/app/ assembleDebug
    

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

    Ограничения


    1. В файле build.gradle проекта должна быть указана версия 'com.android.tools.build:gradle': 2.2.*;
    2. В файлах build.gradle всех модулей должна быть указана buildToolsVersion == 24.0.0;
    3. В файлах build.gradle всех модулей должна быть указана compileSdkVersion <= 24.

    На этом у меня все


    Все скрипты, а также исходный код приложения, можно найти здесь:
    github.com/tabatsky/AStA

    В качестве заключения хочу сказать, что этим методом мне удалось успешно собрать само приложение AStA-app.
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 9
    • 0
      А у вас устройство какой архитектуры? x86 или arm? Если arm, то где вы нашли android sdk для arm?
      А еще развернуть Debian можно очень просто без всяких скриптов и ручной правки конфигов используя LinuxDeploy.
      • 0

        Устройство arm.
        Android SDK взял под x86, установил пакет android-sdk-build-tools из репозитория Debian (отсюда ограничения не версию Debian >= stretch и версию build tools == 24.0.0), скопировал build tools 24.0.0 в папку Android SDK — и всё заработало.


        Про LinuxDeploy и подобные приложения я в курсе. Но в данном конкретном случае мне показалось, что удобнее будет через скрипт.

        • 0
          В тексте видно: «JDK_8_TAR_GZ=jdk-8u144-linux-arm32-vfp-hflt.tar.gz»
        • 0
          Забавно. Осталось запустить на устройстве Android Studio. :-)
          • 0

            Вполне себе запускается через VNC.
            Только вот build-tools оно по умолчанию использует для x86.
            Если аналогичным способом подменить build-tools в его sdk на версию из репозитория debian, по идее должно работать. Но я не пробовал :)

          • 0

            Добавил в приложение простенький текстовый редактор.
            Возможно, в будущем появится и подсветка синтаксиса.

            • 0

              Добавил подсветку синтаксиса для Java.


              Выглядит это примерно так

              image

              • 0

                Уже есть AIDE
                Чем данная альтернатива лучше?

                • 0

                  См. "Какие существуют альтернативы?"

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.