You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current method how the Python app starts and communicates with the Python host works, but it is not very intuitive or fast. If anybody has any advice, feel free to comment or submit a pull request.
Here is an overview on what should happen on the Python app startup, how it's currently implemented and what I don't like about the current implementation:
What should happen
When the user starts the Python app, the Python app has to find a Python interpreter which must provide the paths to the python libraries and the path to the Python home.
If there are multiple Python interpreters installed on the Android device (maybe because of multiple Python versions), the user should be able to choose one of them and set one of them as the default.
The Python app then needs to load these libraries and call a specific native method.
With this implementation, the Python App executes code from an other app. To prevent any security issues, the Python app must be able to ensure that the Python interpreter app has a required permission.
If the method above is used, the user has full control to choose which Python interpreter he wants to use, there are no security issues and the Python files of the Python app are executed in the Python app's process.
Current implementation
Upon startup, the Python app starts an activity with an intent whose action is set to com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO. The intent also contains the package of the Python app as a string and the classpath of an activity-class within the Python app.
If there are multiple apps who can receive the intent, Android displays a chooser-dialogue.
When the activity starts, it immediately starts an other activity.
The component of the intent for this new activity is set to the package and classpath given by the Python app. This means that the new activity points to an activity in the Python app.
The intent also contains a list of paths to the Python libraries.
The Python host can only start the new activity if he has the permission com.python.permission.PYTHONHOST. This is caused by the permission tag in the AndroidManifest of the Python app.
Within the new activity, the Python app loads the libraries and executes the native function startApp. This native function is actually defined in the application library, which is an library of the Python host.
As a consequence, this function must be "linked" with a Java class, before the Python app can call startApp. This is done during loading of the application library within the JNI_OnLoad function. However, in order to register the method to the Java class, the classpath must be known. Since it is not possible to pass any arguments to the JNI_OnLoad function, the classpath gets retrieved via getenv from the environment variable JAVA_PYTHON_MAIN_CLASSPATH.
Unfortunately, Java has no direct way to set an environment variable, instead we need to call setenv via a library that belongs to the Python app.
The classpath is now passed to the JNI_OnLoad function via System.setProperty("python.android.entry.class", ...). There is no native library required.
Drawbacks of the current implementation
There are three activities starting, from which two just redirect to the next activity. I don't think we can get rid of the com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO activity, without taking away the ability to chose, which Python interpreter to use. However, if we could get the package name of the activity which the user chose, we could check if the chosen app has the required permission via [PackageManager.checkPermission](http://developer.android.com/reference/android/content/pm/PackageManager.html#checkPermission%28java.lang.String, java.lang.String%29). The python App would then not use startActivity, instead it would use startActivityForResult. This way, there are only two activities and the whole process is much more intuitive.
It is too slow. I think, if we could change the startup method to the one I proposed in the point above, startup would be much faster.
The Python app needs a native library to set the environment variable. This is the only way I know right now to get the classpath to the JNI_OnLoad function of the application library. I would like the Python app to have no own native libraries, because they require the NDK when building the Python App with our PyToApk-Tool.
Thanks in advance for any help!
Python host: This app.
Python interpreter: Any app with a similar functionality like the Python host.
Python app: Our app, wrapped around someone's Python code, built by our PyToApk-Tool.
The text was updated successfully, but these errors were encountered:
The python host provides the necessary libs to execute Python code.
These libs must be loaded by the Python app. To ensure that there is no
security issue the Python host must have the permission
"com.python.permission.PYTHONHOST".
It's a start, but I think that the starting process of the Python apps
is too complicated, not intuitive and takes too long. If anybody has
advice on that topic, please tell me at issue #9.
Abestanis
added a commit
to Abestanis/APython_PyApp
that referenced
this issue
Jun 29, 2015
Finally!
It's not perfect, but it works.
If anyone has any advice on how to improve the current startup and
communication system, please head over to Abestanis/APython#9.
Summary
The current method how the Python app starts and communicates with the Python host works, but it is not very intuitive or fast. If anybody has any advice, feel free to comment or submit a pull request.
Here is an overview on what should happen on the Python app startup, how it's currently implemented and what I don't like about the current implementation:
What should happen
When the user starts the Python app, the Python app has to find a Python interpreter which must provide the paths to the python libraries and the path to the Python home.
If there are multiple Python interpreters installed on the Android device (maybe because of multiple Python versions), the user should be able to choose one of them and set one of them as the default.
The Python app then needs to load these libraries and call a specific native method.
With this implementation, the Python App executes code from an other app. To prevent any security issues, the Python app must be able to ensure that the Python interpreter app has a required permission.
If the method above is used, the user has full control to choose which Python interpreter he wants to use, there are no security issues and the Python files of the Python app are executed in the Python app's process.
Current implementation
Upon startup, the Python app starts an activity with an intent whose action is set to
com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO
. The intent also contains the package of the Python app as a string and the classpath of an activity-class within the Python app.If there are multiple apps who can receive the intent, Android displays a chooser-dialogue.
When the activity starts, it immediately starts an other activity.
The component of the intent for this new activity is set to the package and classpath given by the Python app. This means that the new activity points to an activity in the Python app.
The intent also contains a list of paths to the Python libraries.
The Python host can only start the new activity if he has the permission
com.python.permission.PYTHONHOST
. This is caused by the permission tag in the AndroidManifest of the Python app.Within the new activity, the Python app loads the libraries and executes the native function
startApp
. This native function is actually defined in theapplication
library, which is an library of the Python host.As a consequence, this function must be "linked" with a Java class, before the Python app can call
startApp
. This is done during loading of theapplication
library within theJNI_OnLoad
function.However, in order to register the method to the Java class, the classpath must be known. Since it is not possible to pass any arguments to theThe classpath is now passed to theJNI_OnLoad
function, the classpath gets retrieved viagetenv
from the environment variableJAVA_PYTHON_MAIN_CLASSPATH
.Unfortunately, Java has no direct way to set an environment variable, instead we need to call
setenv
via a library that belongs to the Python app.JNI_OnLoad
function viaSystem.setProperty("python.android.entry.class", ...)
. There is no native library required.Drawbacks of the current implementation
com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO
activity, without taking away the ability to chose, which Python interpreter to use. However, if we could get the package name of the activity which the user chose, we could check if the chosen app has the required permission via [PackageManager.checkPermission](http://developer.android.com/reference/android/content/pm/PackageManager.html#checkPermission%28java.lang.String, java.lang.String%29). The python App would then not usestartActivity
, instead it would usestartActivityForResult
. This way, there are only two activities and the whole process is much more intuitive.The Python app needs a native library to set the environment variable. This is the only way I know right now to get the classpath to theJNI_OnLoad
function of theapplication
library. I would like the Python app to have no own native libraries, because they require the NDK when building the Python App with our PyToApk-Tool.Thanks in advance for any help!
Python host: This app.
Python interpreter: Any app with a similar functionality like the Python host.
Python app: Our app, wrapped around someone's Python code, built by our PyToApk-Tool.
The text was updated successfully, but these errors were encountered: