📲

Android端末上でAndroidアプリをビルドする

2024/12/13に公開

はじめに

よく電車の中でコーディング&アプリビルドをしたくなる時があります。昨今のAndroidスマホは大きなメモリと高速なSoCを搭載しているので、十分にアプリ開発ができるはず。しかもこれだけ高性能化しているのに、ゲームくらいでしかその性能を存分に味わえないというのはもったいないです(価格もPCと同等ともしくはそれ以上なのに...)。何よりも、手のひらでアプリ開発ができる、というロマンは素晴らしいものがあります。

しかし、意外とAndroid上でAndroid開発するための知見で、最新版に対応したものが少なく地味に苦労したため、備忘録も兼ねて記事にしたいと思います。

Android Studioは現状、直接Android端末にはインストールできません。Termux上などに構築したUbuntu Desktop上にAndroid StudioをGUIで入れるのもできなくはないそうですが、(ちょっと試したところ)挙動が不安定だったりモッサリしていたりするので、あまりベストな感じがしません。今回は、UbuntuをデスクトップなしでTermux上に構築し、その上にCLI上でAndroid環境を整え、コーディングはVSCodeで行なっていくようなスタイルでいきたいと思います。

流れ

  1. Termuxのインストール
  2. Ubuntuのインストール
  3. Android開発環境の構築
  4. aapt2の対応
  5. VSCodeのインストール
  6. おまけ

1. Termuxのインストール

Termuxは、Android用のターミナルエミュレータのアプリで、ルート化不要でLinux環境が使えます。
Play Storeにあるものはどうやら試験版のようで、あまり推奨されていなそうでした。Fdroid版またはGitHubから入れるのが良さそうだったので、自分はGitHub版のtermux-app_vXXX+github-debug_arm64-v8a.apkとなっているものを入れました。

Termuxにストレージへのアクセス許可

Termuxアプリを開き、以下のコマンドでスマホのストレージへのアクセスができるようにします。

Termux
termux-setup-storage

ポップアップまたは遷移した先の画面で、「許可」を押します。
これで、storage/フォルダとしてスマホのストレージの中身が認識されます。

Termux内の各種アップデート

Termux
apt update -y && apt upgrade -y && pkg update -y

(apt updateは、pkgコマンドでインストールを実行するときに自動で実行されるそうですが、念のため)

Termux内の各種インストール

pkgコマンドはTermuxに用意されたパッケージマネージャーで、aptのラッパーとのこと。下記は最小限のものだけ入れているので、必要に応じて追加してください。

Termux
pkg install wget proot -y

2. Ubuntuのインストール

Termux自体もLinuxを動かしているようですが、ファイル構造が違っていたりしてそのままLinuxとして色々いじるにはやや制約が多いとのことでした。(参考)そこで、なじみの深いUbuntuをいれます。
Andronixが配布しているインストーラーを使うと楽に構築できました。

Termux
wget https://raw.githubusercontent.com/AndronixApp/AndronixOrigin/master/Installer/Ubuntu22/ubuntu22.sh -O ubuntu22.sh
chmod +x ubuntu22.sh
./ubuntu22.sh

一度インストールした後は、Termuxで

Termux
./start-ubutnu22.sh

で起動できます。

Ubuntu内の各種アップデート

apt update -y && apt upgrade -y

Ubuntu内の各種インストール

こちらの記事内で使用する最小限のものになります。必要に応じて追加してください。

apt install nano dpkg gpg git zip unzip -y

gpgはVSCodeを入れる際の最後に、Microsoftの最新のリポジトリを入れたいか聞かれる場合があるのですが、yesと答えるときに入っていないとエラーが出るので入れました。(参考)

3. Android開発環境の構築

Android Studioは入れられないので、手動で環境を構築する必要があります。

open-jdkのインストール

apt install openjdk-17-jdk -y

現時点のAndroidProjectで最もよく見かけるバージョン17にて、ひとまずインストールしました。

コマンドラインツールのインストール

Google公式から、「コマンドラインツールのみ」の箇所に移動し、Linux用のcommandlinetools-linux-xxx_latest.zipとなっているファイルをダウンロードします。

スマホのストレージから、Ubuntu内のroot/androidフォルダに解凍します。

Termux
unzip storage/downloads/commandlinetools-linux-xxx_latest.zip -d ubuntu22-fs/root/android

sdkmanagerを使えるようにする

Google公式のガイドの言う通りに、ubuntu22-fs/root/android/cmdline-tools直下にlatestフォルダを作成し、元々あったファイル群をその下に移動します。再度./start-ubuntu22.shでUbuntuに入り、下記のコマンドで移動させます。

mkdir android/cmdline-tools/latest
find android/cmdline-tools -mindepth 1 -maxdepth 1 -not -name "latest" -exec mv {} android/cmdline-tools/latest/ \;
# コマンドが複雑なのは、cmdline-tools配下全てだと移動先である`latest`フォルダも含まれてしまうのを考慮する必要があるため

PATHを通す

ANROID_HOMEなどの環境変数へのパスを通します。エディタはお好みで...

nano ~/.bashrc
~/.bashrc
...
# ファイルの一番下に追加
export ANDROID_HOME=$HOME/android
export PATH=$ANDROID_HOME/cmdline-tools/latest/bin:$PATH
export PATH=$ANDROID_HOME/platform-tools:$PATH

なお、platform-toolsはこの後sdkmanagerで入れます。

変更後はbashを更新します。

source ~/.bashrc
echo $ANDROID_HOME
# /root/android と出れば成功

skdmanagerで各種インストール

パスが無事に通っていれば、下記のコマンドで無事にバージョン情報が確認できます。

sdkmanager --version
# 12.0

最新のプラットフォームツールと、APIレベル34(現時点で最新)のSDKツールをインストールします。

sdkmanager "platform-tools" "platforms;android-34"

残念ながら、emulatorは現時点ではArm64版はないようで、入れようとするとWarning: Failed to find package 'emulator'というエラーが出ました。

その後、下記のコマンドでライセンスを追加承認する必要があります。

sdkmanager --licenses

4. aapt2の対応

試しにビルドしてみる

ここまできたら、一応Android自体のビルドはできるようになっているはずです。試しにnowinandroidをビルドしてみましょう。

StudioProjectsフォルダ配下に、nowinandroidをクローンします。

git clone https://github.com/android/nowinandroid.git ./StudioProjects/nowinandroid

ディレクトリ配下にそのままの名前でクローンするスマートな方法をご存知の方がいたらお教えください汗

その後、試しにdebugビルドしてみましょう。

cd StudioProjects/nowinandroid
./gradlew assembleDebug

./gradlewを使うと、自動でプロジェクトにあったバージョンのgradleのダウンロードが始まるの便利ですね〜

しかし、エラーが出る

残念ながら最後までビルドはできないはずです。なぜなら、Androidのアセット関連を扱うaapt2(Android Asset Packaging Tool)というツールが、Arm64アーキテクチャに対応していないからです。
下記のようなエラーが出るかと思います。

> Task :app:processDemoDebugResources FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDemoDebugResources'.   > Could not resolve all files for configuration ':app:demoDebugRuntimeClasspath'.
   > Failed to transform appcompat-1.7.0.aar (androidx.appcompat:appcompat:1.7.0) to match attributes {artifactType=android-compiled-dependencies-resources, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      > Execution failed for AarResourcesCompilerTransform: /root/.gradle/caches/8.10/transforms/4a06d29f5dfb54242d37464d1409aabe/transformed/appcompat-1.7.0.
         > AAPT2 aapt2-8.6.1-11315950-linux Daemon #0: Daemon startup failed

Arm64版aapt2に置換する

これへの対処方法を、こちらのQiita記事で書いてくださっていました。なお、Arm64版aapt2の入手先が古くなってしまっていたので、新しい入手先を探して入手しました。

入手先がこちら↓
https://github.com/lzhiyong/android-sdk-tools/releases

android-sdk-tools-static-aarch64.zipというファイルをダウンロードして解凍すると、build-toolsフォルダから、aapt2のバイナリファイルが入手できます。自分はPCで解凍してから、aapt2だけをスマホに移動させました。

Termux
cp storage/downloads/aapt2 ubuntu22-fs/root/aapt2

このバイナリファイルを、Qiita記事のように、/root/.gradle/caches/modules-2/files-2.1/com.android.tools.build/aapt2配下にある、graldeバージョンごとのキャッシュディレクトリの下に、aapt2-xxx-linux.jarというファイルがあるので、その中のaapt2バイナリと置換します。
具体的には、aapt2-xxx-linux.jarを一旦zipにして解凍し、中身のaapt2を置換して、再度jarにして戻します。

以下は、コマンドの一例です。フォルダ名は適宜変えてください。

cp .gradle/caches/modules-2/files-2.1/com.android.tools.build/aapt2/8.6.1-11315950/ab3cd0771ff191abb65decd83b99fb6ba795ca02/aapt2-8.6.1-11315950-linux.jar aapt2-8.6.1-11315950-linux.zip

unzip aapt2-8.6.1-11315950-linux.zip -d unzip-jar

rm aapt2-8.6.1-11315950-linux.zip

mv aapt2 unzip-jar/aapt2

cd unzip-jar #移動せずに行うと、unzip-jar/*という形でzip化されて、ビルド時に失敗した
zip aapt2-8.6.1-11315950-linux.zip *
cd

mv unzip-jar/aapt2-8.6.1-11315950-linux.zip .gradle/caches/modules-2/files-2.1/com.android.tools.build/aapt2/8.6.1-11315950/ab3cd0771ff191abb65decd83b99fb6ba795ca02/aapt2-8.6.1-11315950-linux.jar

再度ビルドを実行

置換が完了したら、再度./gradlew assembleDebugを実行します。

すると...無事にビルドが完了します!
自分の端末だと何度かTermuxが落ちて、そのたびに再実行する必要がありました。しかしちゃんと記録が蓄積されていくので、何度もやれば着実にビルドが進んでいきます。gradle.propertiesのJVMメモリの設定をいろいろいじると起きづらくなった気がします。-Xmx=2500mにしたらデバッグビルドだと一度も落ちませんでした。小さすぎるとそれはそれでエラーが出ました。

./gradlew assembleDebug
感動のBuild Successfulの文字

./gradlew assembleRelease
assembleReleaseもいけました

5. VSCodeのインストール

TermuxのCLI上でコーディングをするのはさすがにキツイため、モダンなエディタを使いたいところです。VSCodeをUbuntuに入れて、VSCode Serverとして使うのが一番良さそうでした。通常のWeb版VSCodeであるvscode.devだと何度やってもGitHubログインや一部プラグインのインストールができなかったのですが、Ubuntu上に立てたVSCode Serverだと、無事にできました。

公式サイトからArm64版.debパッケージをダウンロードします。(code_xxx_arm64.debという名前でした。amd64とややこしいので注意)
その後、以下のようにしてスマホのストレージからUbuntuに移動させます。Ubuntu内に入っている場合は、一旦exitコマンドでTermuxに出ておきます。

Termux
cp storage/downloads/code_xxx_arm64.deb ubuntu22-fs/root/code.deb

その後、Ubuntuを./start_ubuntu22.shで再度起動し、Ubuntu内にインストールします。

apt install ./code.deb -y

無事にインストールできたら、下記のコマンドで開始し、ブラウザでURLを開きます。

code serve-web

通常のスマホ画面だとせまくて要素がギチギチになってしまうので、Androidの設定アプリの「開発者向けオプション」→「最小幅」を、500dp〜600dpに設定すると画面が広々使えるようになりました。(この設定にしてからZenn記事もスマホ上で編集しやすくなりました。)

before: 411dp after: 520dp
dpi before dpi after

PWAとしてスマホのホーム画面に追加できるのが嬉しいところです。
vscode pwa

6. おまけ

端末のアーキテクチャを確認

Termux
pkg install neofetch
neofetch

これを実行すると下記のようなロマン溢れるASCIIアートと共に端末のアーキテクチャが確認できます(ただしデフォルトのTermuxのズームレベルだと見切れる可能性があるので、ピンチインしてから実行するのが良さそう)

termux_neofetch

TODO:

ビルドしたapkファイルをスムーズに端末に移動させて起動するフローを構築したいです。

おわりに

Android内でアプリ開発ができる、この感動は素晴らしいです。モバイル開発onモバイル端末の同志が他にいらっしゃいましたら、ぜひ繋がりたいです。
何か内容に間違いなどございましたら、コメントでご指摘くださいますと幸いです。

参考

https://dev.to/junaid_dev/setup-official-vs-code-on-android-5a

https://stackoverflow.com/questions/76763954/android-app-development-with-visual-studio-code

https://zenn.dev/link/comments/dd25e01c1d9426

https://issuetracker.google.com/issues/227219818

https://qiita.com/tacchi/items/ec63aa8bff5103982156

Discussion