Android 上で Android Studio を使わずに C/C++ で Android アプリを開発してみる

## 概要

Android 端末上に、Android ネイティブ向けのビルド環境を構築し、 Android ネイティブ向けのアプリを作成するまでの手順を、詳細を省いて説明します。

Termux での開発では、クロスコンパイルが困難であるため、ホストと同じアーキテクチャへの出力を行います。

今回は GUI ライブラリに **DXライブラリ Android 版**を使用しています。


手元の開発環境を [GitHub](https://github.com/nokotan/DxLibAppDevOnAndroid) にアップロードしています。適宜使ってください。

以下は少し前に、DXライブラリ Android 版を使ったアプリ開発 on Termux を試したものです。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">AndroidでAndroidアプリ(DXライブラリ使用)を開発してみたのです<a href="https://twitter.com/hashtag/Android?src=hash&amp;ref_src=twsrc%5Etfw">#Android</a> <a href="https://twitter.com/hashtag/DX%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA?src=hash&amp;ref_src=twsrc%5Etfw">#DXライブラリ</a> <a href="https://twitter.com/hashtag/termux?src=hash&amp;ref_src=twsrc%5Etfw">#termux</a> <a href="https://t.co/vCCEV16pcs">pic.twitter.com/vCCEV16pcs</a></p>&mdash; かめのこにょこにょこ (@kamenoko_dev) <a href="https://twitter.com/kamenoko_dev/status/1320973898230370304?ref_src=twsrc%5Etfw">October 27, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 検証環境

| 項目名 |||
|:--:|:--:|:--:|
| 端末 | Android Emulator | Aquos Phone Sense6 |
| OS | Android 11 | Android 12 |
| CPU Architecture | x86_64 | arm64 |

## Termux のインストール

[Google Play](https://play.google.com/store/apps/details?id=com.termux) または [F-Droid](https://f-droid.org/en/packages/com.termux/)[^version-aware] から termux をインストールしてください。

[^version-aware]: Android SDK 29 以降の SELinux の W^X ポリシーの強化と、Google Play が受け付けるアプリの最低 SDK バージョンの引き上げのため、Play Store 版の機能更新ができない状況になっています。詳細は [Termux and Android 10](https://github.com/termux/termux-packages/wiki/Termux-and-Android-10) を確認してください。

## 必要なパッケージのインストール

```sh
pkg install curl build-essential aapt openssl-tool apksigner
# それと適当なテキストエディタ
pkg install vim
```

## DXライブラリ Android版のダウンロードと解凍

```sh
curl -o DxLib.zip https://dxlib.xsrv.jp/DxLib/DxLib_Android3_22a.zip
unzip -oCP932 DxLib.zip
```

## ソースファイルを書く

[Android版の注意点](https://dxlib.xsrv.jp/use/dxuse_android_studio_4_0.html) (Windows版にあってAndroid版にない関数、ファイルパッケージングの制約など) に気を付けながら適当に書いてください。

```cpp
#include <DxLib.h>

int android_main() {
  if (DxLib_Init() == -1) {
    return 0;
  }

  while (ProcessMessage() == 0) {
    ClearDrawScreen();
    DrawBox(0, 0, 300, 300, GetColor(255, 0, 0), TRUE);
    ScreenFlip();
  }

  DxLib_End();
}
```

## ビルドスクリプトの記述

依存ライブラリが非常に多いのと、ライブラリ同士の依存関係に注意が必要です。

```sh
clang -o libmain.so --shared --fPIC \
  Main.cpp \
  -I<DXライブラリへのパス>/<アーキテクチャ> \
  -L<DXライブラリへのパス>/<アーキテクチャ> \
  -landroid -lGLESv1_CM -lEGL -lstdc++ -lGLESv2 -lOpenSLES \
  -lm -lDxLib -lDxUseCLib -ljpeg -lpng -lzlib -ltiff \
  -ltheora_static -lvorbis_static -lvorbisfile_static -logg_static \
  -lbullet -lopus -llog -ldl
# TODO: CMakeFile を使いたい
```

## AndroidManifest.xml の記述

知識がないので、[android/ndk-samples](https://github.com/android/ndk-samples/blob/master/native-activity/app/src/main/AndroidManifest.xml) をほぼそのまま使用

## パッケージングスクリプトの記述

```sh
cp libmain.so lib/<アーキテクチャ>
cp $PREFIX/lib/libc++_shared.so lib/<アーキテクチャ>

aapt package -M AndroidManifest.xml -F app.apk -f
aapt add app.apk lib/<アーキテクチャ>/libmain.so
aapt add app.apk lib/<アーキテクチャ>/libc++_shared.so
```

## APK 署名の準備

`keytool` が termux では使えそうにないので、[OpenSSL を使って手動生成](https://source.android.google.cn/devices/tech/ota/sign_builds?hl=ja#manually-generating-keys) しました。

```sh
openssl genrsa -3 -out key.pem 2048
openssl req -new -x509 -key key.pem -out key.x509.pem -days 10000 -subj '/'
openssl pkcs8 -in key.pem -topk8 -outform DER -out key.pk8 -nocrypt
```

## APK への署名

```sh
apksigner sign --key key.pk8 --cert key.x509.pem app.apk
```

## 作った APK のインストール

手元の環境では、ファイルアプリから Termux が公開するストレージを開いて、それから .apk をタップしてインストールできました。
環境によっては、SDカードのダウンロードに移したり、提供元不明のアプリのインストールを許可したりする必要があると思われます。

![TermuxInFile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158514/ee5ec8a7-b217-cd27-883c-c04e128d21e5.png)

## あとがき

これが筆者のはじめての Android ネイティブアプリ作成であり、あちらこちらにバッドノウハウがちりばめられていると思います。
それと、手順が煩雑すぎるくせに、単一アーキテクチャにしか対応できないなど、どう考えても手軽とはいきません。

しかし、Android上でAndroidネイティブアプリを手軽に制作できる環境の潜在需要は、おそらく非常に大きいと考えている故、
私より強いAndroidエンジニアがこの記事を踏み台にしていくことを望んでいたりします。