Skip to content

Instantly share code, notes, and snippets.

@alanjds
Forked from tito/README
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alanjds/020d95292d3f2fff9f85 to your computer and use it in GitHub Desktop.
Save alanjds/020d95292d3f2fff9f85 to your computer and use it in GitHub Desktop.
P4A_pyjnius_DIR=~/code/pyjnius ./distribute.sh -b minimal -m 'pyjnius python' -u pyjnius
cd .; ./build.py --package org.minimal.test --name _MINIMAL --version 1 --private ~/code/testmininal --asset debug installd
adb logcat *:S python:D
--- a/jnius/jnius_jvm_android.pxi
+++ b/jnius/jnius_jvm_android.pxi
@@ -1,5 +1,16 @@
# on android, rely on SDL to get the JNI env
-cdef extern JNIEnv *SDL_ANDROID_GetJNIEnv()
+ctypedef (JNIEnv *)(*f_android_get_jnienv)()
+cdef extern from "dlfcn.h":
+ ctypedef char const_char "const char"
+ void *dlsym(void *handle, const_char *symbol)
+ void *RTLD_GLOBAL
cdef JNIEnv *get_platform_jnienv():
- return SDL_ANDROID_GetJNIEnv()
+ from os import environ
+ symbol = environ.get(
+ "PYJNIUS_JNIENV_SYMBOL", "SDL_ANDROID_GetJNIEnv")
+ cdef char *c_symbol = symbol.encode("utf-8")
+ cdef f_android_get_jnienv fn = <f_android_get_jnienv>dlsym(RTLD_GLOBAL, c_symbol)
+ if fn == NULL:
+ return NULL
+ return fn()
diff --git a/setup.py b/setup.py
index b1cefb7..070703b 100644
--- a/setup.py
+++ b/setup.py
@@ -41,7 +41,7 @@ except ImportError:
if platform == 'android':
# for android, we use SDL...
- libraries = ['sdl', 'log']
+ #libraries = ['sdl', 'log']
library_dirs = ['libs/' + environ['ARCH']]
elif platform == 'darwin':
import objc
import androidembed
print "Hello world, we are entering in a loop!"
import jnius
print "tried importing jnius"
from jnius import accelerometer
print "jnius imported"
accelerometer.enable()
print "accelerometer enabled"
while androidembed.poll(1000):
print "->", accelerometer.acceleration
print "We leaved our hello world!"
diff --git a/bootstrap/minimal/jni/main.c b/bootstrap/minimal/jni/main.c
index f7b0ba1..c03dbf5 100644
--- a/bootstrap/minimal/jni/main.c
+++ b/bootstrap/minimal/jni/main.c
@@ -13,8 +13,13 @@
#endif
struct android_app *g_state = NULL;
+static JNIEnv *g_env = NULL;
+JNIEnv *minimal_get_jnienv() {
+ return g_env;
+}
+
static PyObject *androidembed_poll(PyObject *self, PyObject *args) {
int indent;
int events;
@@ -96,6 +101,8 @@ void android_main(struct android_app* state) {
//env_argument = getenv("ANDROID_ARGUMENT");
//setenv("ANDROID_APP_PATH", env_argument, 1);
//setenv("PYTHONVERBOSE", "2", 1);
+ setenv("PYJNIUS_JNIENV_SYMBOL", "minimal_get_jnienv", 1);
+ setenv("ANDROID_ARGUMENT", "", 1); // needed for plyer
Py_SetProgramName("python-android");
Py_Initialize();
//PySys_SetArgv(argc, argv);
@@ -108,23 +115,22 @@ void android_main(struct android_app* state) {
// get the APK filename, and set it to ANDROID_APK_FN
ANativeActivity* activity = state->activity;
- JNIEnv* env = NULL;
- (*activity->vm)->AttachCurrentThread(activity->vm, &env, 0);
- jclass clazz = (*env)->GetObjectClass(env, activity->clazz);
- jmethodID methodID = (*env)->GetMethodID(env, clazz, "getPackageCodePath", "()Ljava/lang/String;");
- jobject result = (*env)->CallObjectMethod(env, activity->clazz, methodID);
+ (*activity->vm)->AttachCurrentThread(activity->vm, &g_env, 0);
+ jclass clazz = (*g_env)->GetObjectClass(g_env, activity->clazz);
+ jmethodID methodID = (*g_env)->GetMethodID(g_env, clazz, "getPackageCodePath", "()Ljava/lang/String;");
+ jobject result = (*g_env)->CallObjectMethod(g_env, activity->clazz, methodID);
const char* str;
jboolean isCopy;
- str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
+ str = (*g_env)->GetStringUTFChars(g_env, (jstring)result, &isCopy);
LOGI("Looked up package code path: %s", str);
setenv("ANDROID_APK_FN", str, 1);
- methodID = (*env)->GetMethodID(env, clazz, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
- jobject appInfo = (*env)->CallObjectMethod(env, activity->clazz, methodID);
- jfieldID fieldID = (*env)->GetFieldID(env,
- (*env)->GetObjectClass(env, appInfo), "nativeLibraryDir", "Ljava/lang/String;");
- result = (*env)->GetObjectField(env, appInfo, fieldID);
- str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
+ methodID = (*g_env)->GetMethodID(g_env, clazz, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
+ jobject appInfo = (*g_env)->CallObjectMethod(g_env, activity->clazz, methodID);
+ jfieldID fieldID = (*g_env)->GetFieldID(g_env,
+ (*g_env)->GetObjectClass(g_env, appInfo), "nativeLibraryDir", "Ljava/lang/String;");
+ result = (*g_env)->GetObjectField(g_env, appInfo, fieldID);
+ str = (*g_env)->GetStringUTFChars(g_env, (jstring)result, &isCopy);
LOGI("Looked up library code path: %s", str);
setenv("ANDROID_LIB_PATH", str, 1);
diff --git a/recipes/plyer/recipe.sh b/recipes/plyer/recipe.sh
index 5d47356..f3321b3 100644
--- a/recipes/plyer/recipe.sh
+++ b/recipes/plyer/recipe.sh
@@ -2,7 +2,7 @@
VERSION_plyer=${VERSION_plyer:-master}
URL_plyer=https://github.com/kivy/plyer/zipball/$VERSION_plyer/plyer-$VERSION_plyer.zip
-DEPS_plyer=(pyjnius android)
+DEPS_plyer=(pyjnius)
MD5_plyer=
BUILD_plyer=$BUILD_PATH/plyer/$(get_directory $URL_plyer)
RECIPE_plyer=$RECIPES_PATH/plyer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment