![見出し画像](https://assets.st-note.com/production/uploads/images/86082994/rectangle_large_type_2_2cb0717686c031211e964501800a4da2.png?width=800)
AndroidからPythonを独立実行・単独で動くアプリ開発 - Chaquopyの環境構築
AndroidでPythonを動かすといった場合…
次の2つの解釈ができます。
外部アプリのPythonからスクリプト実行
アプリにPythonを組み込んで単独実行
ググると前者の方法が沢山出てきます。
知りたいのは そういうことじゃないんだよ (-_-;)
また後者の方法もヒットするにはヒットしますが、JavaあるいはKotlin(つまりAndroid SDK)と連携させる感じのライブラリ・技術は中々見つかりません。
でも最近とても良いものを見つけました。
その名も Chaquopy というライブラリ
※ 読み方は「チャコパイ」かもしれない
以下の特徴を備えています
アプリ単独でPythonを独立実行できる
外部ライブラリのインポートも可能
Java・Kotlinとの相互連携にも対応してる
そして実際に使ってみました。
とても使い心地もよかったので、
同じように使ってみたい人向けに導入から解説します。
1.settings.gradleにMavenリポジトリを追加
まずsettings.gradleを開きます。
▼ この赤枠で囲ったファイル
![](https://assets.st-note.com/img/1662175348388-lE5dDO3fAy.png)
▼ 最初はこのような内容になってるはず
rootProject.name = "SampleApp"
include ':app'
この2行の記述の前に以下を追加してください
▼ 必ず"前"に追加!後ろではない(強調)
pluginManagement {
repositories {
maven { url "https://chaquo.com/maven" }
}
}
かならず一番最初に追加しないとダメです。
2.build.gradleにChaquopyプラグインを追加
お次はbuild.gradleの設定
まずプロジェクトレベルのbuild.gradleを開きます。
▼ 2つあるけど赤枠で囲んだこっち
![](https://assets.st-note.com/img/1662182647909-O03rIc8XYh.png)
▼ そこでallprojectsの前に以下を追加
buildscript {
...
}
/// 以下を追加する!
plugins {
id 'com.chaquo.python' version '11.0.0' apply false
}
allprojects {
...
}
これでChaquopyのバージョンを指定
続いてアプリレベルのbuild.gradleを開きます。
▼ 今度はこの赤枠で囲んだもの
![](https://assets.st-note.com/img/1662182680890-qhrKeLO4Vv.png)
▼ そこで次のpluginsの記述を探す
plugins {
id 'com.android.application'
id 'kotlin-android'
}
▼ ここに com.chaquo.python を追加
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.chaquo.python'
}
※ この状態で Sync Now するとエラーが出る
それは気にせずに次の設定に進みます。
3.PythonインタプリターのabiFiltersを設定
Pythonインタプリタを動かすにはABI設定が必要です。
ABI = アプリ バイナリ インターフェース
つまり動作環境でネイティブに動かせるってこと
▼ 設定するにはアプリレベルのbuild.gradleを開く
![](https://assets.st-note.com/img/1662182680890-qhrKeLO4Vv.png)
▼ 次のdefaultConfigの記述を見つける
android {
compileSdkVersion 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.hoge.example"
minSdkVersion 21
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
▼ そこに次みたく apiFilters を追加する
android {
compileSdkVersion 31
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.hoge.example"
minSdkVersion 21
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
/// 追加!!
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
}
以下はapiFiltersにABIの対応リスト
armeabi-v7a : 全Android端末に対応
arm64-v8a : 最新Android端末のみ対応
x86 : Androidエミュレーター向け
x86_64 : こちらもAndroidエミュレーター向け
各ABI追加でアプリ容量は数十MBほど増えます。
▼ ちなみにABIについて・・・
Android端末ごとにCPUが異なるため、サポートされる命令セットも違います。各CPUと命令セット向けに用意されたインターフェースがABIというわけです。
上記の公式リファレンスでも各ABIがどの命令セットと対応するのか細かく解説されてます。現時点ではABIの種類は4種類だけのようです。
4.build.gradleにてbuildPythonの設定
いくつかの機能はPython3.5以上が要求される模様
その機能の利用にはビルド用Pythonの指定が必要です
だからPythonをローカル開発環境にインストールしてください
▼ 参考になりそうな記事
▼ Windowsの場合 : Pythonのパスを調べる
> where python
C:\path\to\python.exe
Pythonをインストール&パスを調べてください
そしたらアプリレベルのbuild.gradleを再度開きます。
▼ defaultConfig内に以下を追加する
defaultConfig {
applicationId "com.hoge.example"
minSdkVersion 21
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
/// 先ほど追加したNDK設定
ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
/// 追加!!
python {
buildPython "C:/path/to/python.exe"
}
}
これで一通りの設定は完了です。
5.AndroidManifest.xmlに初期化設定追加
いよいよ本題に入っていきます。
アプリ側でのPythonの初期化について
もしなんの設定もしない場合、ActivityやらServiceの初めに Python.start() を呼び出す必要があります。局所的にPythonを使うならそれでもいいかも
でもアプリ全体を通してPythonを使う場合、次のようにAndroidManifest.xmlに初期化属性を追加しておいた方がいいです。
▼ 以下のようにcom.chaquo.python.android.PyApplication を追加
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name="com.chaquo.python.android.PyApplication">
<!-- Activityとか...(省略) -->
</application>
必ず追加しておいてください。
6.KotlinからPythonコードを実行してみる
いよいよ待ちに待ったPythonの実行です
まず src/main/python にpyスクリプトを作成します。
▼ つまりこのような状態
![](https://assets.st-note.com/img/1662183405222-TppzkjTzt6.png)
▼ hello.pyの中身
val = 100
def hello(name):
return 'Hello '+name+" !!"
もしpythonディレクトリがないなら作ってください
そしたらKotlin(java)側で次のコードを書きます。
▼ hello.pyの変数valの値を表示してみよう
class MainActivity : AppCompatActivity() {
companion object{
val TAG = MainActivity.javaClass.simpleName
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/// Pythonインスタンス取得
val py = Python.getInstance()
/// モジュールから値とか関数呼び出し
val hello:PyObject = py.getModule("hello")
/// 変数を表示してみよう
Log.d(TAG, "val : "+hello.get("val"))
}
}
▼ 出力結果
val : 100
ということで無事AndroidからPython実行できました。
重要なのはPythonが外部アプリに起動せず、本当に独立したPythonコードとしてアプリ内から実行されていることです。
生成されたAPKバイナリを解析してみるとassetsデイレクトリに実行に必要なバイナリが格納されているようです。(詳細は一切分からない)
でも独立してAndroidアプリからPythonを呼び出せる
本当に素晴らしい技術だと感心しました。
もちろん次のようなことも可能です。
Kotlin/Javaからpython関数の呼び出し
PythonからKotlin/Javaメソッド呼び出し
pipによるライブラリインストール
それはまた別のnoteとかでまとめたいと思います。
しばらくはChaquopyで色々遊んでみる予定です。
この記事が気に入ったらサポートをしてみませんか?