I want to run some Python code from Android through JNI using NDK like this:
#include <jni.h>
#include <string>
#include <stdio.h>
#include <Python.h>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_mypythonapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */)
{
std::string command = "print('Hello World from Python!!!')";
PyObject* pInt;
Py_Initialize();
PyRun_SimpleString(command.c_str());
Py_Finalize();
std::string message = "Command ";
message.append(command);
message.append(" was executed successfully!")
return env->NewStringUTF(message.c_str());
}
Are there prebuilt libpython
available for Android or is there any way to cross compile it in order to be able to achieve that?
Python
for Android
with:┌─[19:20:55]─[jacob@jacob-pc]─[~]
└──> export ANDROID_NDK_ROOT=/path/to/android-ndk
┌─[19:20:55]─[jacob@jacob-pc]─[~]
└──> ./configure CC=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang CXX=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ AR=aarch64-linux-android-ar LD=aarch64-linux-android-ld RANLIB=aarch64-linux-android-ranlib --target=arm-linux-androideabi -prefix=/path/to/install/dir --enable-shared --without-sqlite3 --without-pdo-sqlite --without-pear --enable-simplexml --disable-mbregex --enable-sockets --enable-fpm --disable-opcache --enable-libxml --without-zlib --build=x86_64-linux-gnu --disable-all --disable-ipv6 ac_cv_have_long_long_format=yes ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no
┌─[19:20:55]─[jacob@jacob-pc]─[~]
└──> make
┌─[19:20:55]─[jacob@jacob-pc]─[~]
└──> make install
Or, easier, using docker:
┌─[19:20:55]─[jacob@jacob-pc]─[~]
└──> docker run --rm -it -v $(pwd):/python3-android -v /path/to/android-ndk:/android-ndk:ro --env ARCH=arm --env ANDROID_API=21 python:3.9.0-slim /python3-android/docker-build.sh
replacing /path/to/android-ndk
with the path to the Android NDK.
Deploy the resulted folder inside an readable folder on your Android
system then call Py_SetPythonHome
providing that path.
Be aware that it is probably necessary to run:
Py_Initialize();
std::string command = "print('hello world')";
PyRun_SimpleString(command.c_str());
Py_Finalize();
on a thread other than the Java thread.
Tested with 21.1.6352462
, Python 3.8.6
and Python 3.9.0
.