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

в 22:07, , рубрики: Android OS, Android sdk, android studio, Debian, gradle, JDK, Разработка под android

Что такое 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/cPermitRootLogin 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.

Автор: jatx

Источник

Поделиться

* - обязательные к заполнению поля