Mobile application development on Android is traditionally associated with Java or Kotlin, but what to do if your project requires capabilities Python? For example, for working with machine learning libraries (TensorFlow Lite, PyTorch Mobile), data processing (Pandas, NumPy) or using ready-made scripts. Fortunately, integrating Python into Android Studio is possible - and this opens up new horizons for hybrid applications.
In this article we will examine three officially supported ways to add Python to Android projects: through a plugin Chaquopy (recommended by Google), manual assembly with Python for Android and the use of REST API for transferring logic to the server. We will pay special attention to setting up the environment, solving common errors (for example, java.lang.UnsatisfiedLinkError when working with native libraries) and optimizing performance. If you have never worked with Python in mobile development, no problem: the instructions are adapted for beginners, but also contain advanced tips for experienced developers.
Before you begin, make sure that your project meets the minimum requirements:
- ๐ฑ Android Studio version 2022.3.1 or later (check in
Help โ About) - ๐ Installed Python 3.8+ (recommended 3.10 for Chaquopy)
- ๐ฆ Project on Gradle 7.4+ (update in
gradle-wrapper.properties) - ๐ Connect to the Internet to download dependencies (Chaquopy requires ~500 MB when first launched)
1. Method 1: Chaquopy - an official plugin from Google
Chaquopy is the easiest and most supported way to integrate Python into Android. The plugin automatically compiles Python code to bytecodewhich runs on the device through the built-in interpreter. Advantages:
- โ Full support for most. Python libraries (including NumPy, SciPy, OpenCV)
- โ Integration with Android Studio at the Gradle level (no need for manual assembly)
- โ Ability to debug Python code directly in the IDE
- โ ๏ธ Limitation: libraries with C-extensions (for example TensorFlow full version)
To connect Chaquopy, follow these steps:
- Open the file
build.gradle(project level) and add the repository to the blockbuildscript โ repositories:maven { url "https://chaquo.com/maven" } - In the same file add a dependency to
dependencies:classpath "com.chaquo.python:gradle:14.0.0" - In the file
build.gradle(module level) apply the plugin and specify the Python version:apply plugin: 'com.chaquo.python'android {
defaultConfig {
python {
version "3.10"
}
}
} - Synchronize the project with Gradle (button
Sync Nowin the upper right corner).
Add repository Chaquopy in buildscript|Indicate plugin dependency|Apply plugin in module|Indicate Python version|Synchronize Gradle-->
After synchronization, a folder will appear in the project structure. Create a file in it, for example, python. Create a file in it, for example, script.py, and write test code:
def greet(name):return f"Hello, {name} from Python!"
def calculate_sum(a, b):
return a + b
Now you can call these functions from Kotlin/Java. Example for MainActivity.kt:
if (!Python.isStarted()) {Python.start(AndroidPlatform(this))
}
val python = Python.getInstance()
val module = python.getModule("script")
// Calling the greet function
val greeting = module.callAttr("greet", "Android").toString()
Log.d("Python", greeting)
// Calling the calculate_sum function
val sum = module.callAttr("calculate_sum", 5, 3).toInt()
Log.d("Python", "Sum: $sum")
If the first time you run Chaquopy it gives an error No such file or directory, check that the repository is enabled in settings.gradle Google: google(). Also clear the Gradle cache via File โ Invalidate Caches.
2. Method 2: Python for Android (Kivy) - for self-assembly
If Chaquopy is not suitable (for example, due to limitations on libraries), an alternative would be Python for Android a tool from the team Kivy. It allows you to build full-fledged APKs with Python code, but requires manual configuration. This method is suitable for:
- ๐ฎ Development of games on Kivy or Pygame
- ๐ค Applications with complex native extensions (for example, TensorFlow full version)
- ๐ฆ Projects where a full control over the assembly
The main disadvantage is increasing the APK size (up to 20โ50 MB due to the built-in Python interpreter). Also, the assembly process is more complicated than in Chaquopy.
Setup instructions:
- Install Python for Android via
pip:pip install python-for-android - Create a file
buildozer.specin the root of the project with minimal configuration:[app]title = MyApp
package.name = myapp
package.domain = org.example
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
version = 0.1
requirements = python3,kivy
android.api = 31
android.minapi = 21
android.ndk = 23b
android.sdk = 33 - Build the APK with the command:
buildozer -v android debugโ ๏ธ Attention: Building can take up to 30 minutes and will require ~5 GB of free space. Use
--privatefor local assembly without downloading dependencies.
| Option | Chaquopy | Python for Android |
|---|---|---|
| Library support | Partial (no C extensions) | Full (including TensorFlow) |
| APK size | ~5โ10 MB | ~20โ50 MB |
| Configuration complexity | Low (Gradle plugin) | High (manual assembly) |
| Debugging | In Android Studio | Via adb logcat |
Chaquopy|Python for Android (Kivy)|REST API (server logic)|Not decided yet-->
3. Method 3: Moving the logic to the server (REST API)
If your application does not require offline work with Python, the most reliable way is to move the logic to the server and communicate with it via REST API or WebSocket. This solution is suitable for:
- ๐ Applications with cloud data processing (for example, analytics)
- ๐ Projects where security is important (code is not disclosed in the APK)
- โก Applications with high performance requirements
Disadvantages: a backend is required (you can use FastAPI, Flask or Django) and a stable Internet connection. Example architecture:
- An Android application sends a request to the server (for example, JSON with data).
- The server processes the request using Python and returns the result.
- The application receives the response and displays it to the user.
Example code for FastAPI (server):
from fastapi import FastAPIimport uvicorn
app = FastAPI()
@app.post("/process")
async def process_data(data: dict):
# Data processing using Python
result = {"status": "success", "data": data["input"] * 2}
return result
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Example request from Android (Kotlin s Retrofit):
interface ApiService {@POST("process")
suspend fun processData(@Body request: Map
): Response }
// Call
val retrofit = Retrofit.Builder()
.baseUrl("http://your-server-ip:8000/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(ApiService::class.java)
val response = service.processData(mapOf("input" to 5))
How to reduce delays when working with API?
Use caching responses using Room Database or SharedPreferences.
For critical operations, implement request queue s WorkManager.
If the server and client are on the same network, use local IP instead of a public domain (reduces latency by 2-3 times).
4. Solving common errors when integrating Python
Even with proper configuration, you may encounter errors. Here are the most common ones and how to fix them:
Error 1: java.lang.UnsatisfiedLinkError (native library missing)
Arises when the Python library requires compiled .sofiles, but Chaquopy does not have them found it. Solution:
- ๐ง Add the library to
build.gradleto the blockpython:python {pip {
install "opencv-python" // Example for OpenCV
}
} - ๐ฆ Make sure that the library version is compatible with Android (check on the official Chaquopy website).
Error 2: Python not started
Frequent error on first launch. Reasons:
- ๐ซ Not called
Python.start()before use. - ๐ต No permissions to access the storage (Chaquopy requires
WRITE_EXTERNAL_STORAGEfor cache). - ๐ Python version conflict (for example, specified
3.10and Chaquopy tries use3.8).
Solution: add to AndroidManifest.xml permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And initialize Python in onCreate:
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
if (!Python.isStarted()) {
Python.start(AndroidPlatform(this))
}
}
Error 3: ModuleNotFoundError
Python does not find your module. Check:
- ๐ The file is in the folder
src/main/python(and not inassetsorres). - ๐ค The module name is specified without an extension (for example,
scriptand notscript.py). - ๐ After changes in the Python code, run
Build โ Rebuild Project.
90% of Chaquopy errors are related to incorrect Gradle configuration or lack of rights. Always check the logs through Logcat with a filter by tag python.
5. Android
Python runs slower on mobile devices than native code. To speed up execution:
Tip 1: Use Numba or Cython for critical areas
These tools compile Python to optimized bytecode or C. The example with Numba:
from numba import jit@jit(nopython=True)
def fast_calculation(a, b):
return a 2 + b 2
โ ๏ธ Attention: Numba requires additional configuration in Chaquopy. Add to build.gradle:
python {pip {
install "numba==0.56.4" // Version must be supported by Chaquopy
}
}
Tip 2: Move heavy calculations to a background thread
Python code blocks UI streamwhich leads to ANR (Application Not Responding). Use Coroutines or RxJava:
lifecycleScope.launch(Dispatchers.IO) {val result = module.callAttr("heavy_function", data)
withContext(Dispatchers.Main) {
textView.text = result.toString()
}
}
Tip 3: Cache results
If a function returns the same result for the same input data, cache it with functools.lru_cache:
from functools import lru_cache@lru_cache(maxsize=128)
def expensive_operation(x, y):
# Long calculations
return result
| Optimization method | Acceleration | Complexity of implementation |
|---|---|---|
| Numba/Cython | 2โ10 times | Average |
| Background threads | Eliminates ANR | Low |
| Caching | up to 100 times (for repeated calls) | Low |
| Simplification of algorithms | depends on the code | High |
6. Examples of real projects with Python in Android
To get inspired, consider several successful cases of using Python in mobile applications:
Example 1: Image processing with OpenCV
An application for text recognition in photographs (OCR) can use OpenCV i Tesseract:
# script.pyimport cv2
import pytesseract
def recognize_text(image_path):
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
text = pytesseract.image_to_string(gray)
return text
On the Android side:
// Photo captureval imageFile = File(externalCacheDir, "photo.jpg")
// Call Python
val text = module.callAttr("recognize_text", imageFile.absolutePath)
Example 2: Machine learning with TensorFlow Lite
Chaquopy does not support the full TensorFlow, but you can use TensorFlow Lite:
# script.pyimport tflite_runtime.interpreter as tflite
def predict(image_data):
interpreter = tflite.Interpreter(model_path="model.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
interpreter.set_tensor(input_details[0]['index'], image_data)
interpreter.invoke()
return interpreter.get_tensor(output_details[0]['index'])
โ ๏ธ Attention: Model model.tflite must be in assets and copied to the storage upon first launch.
Example 3: Parsing data from Pandas
Analysis of CSV files directly on device:
# script.pyimport pandas as pd
def analyze_data(file_path):
df = pd.read_csv(file_path)
return {
"mean": df.mean().to_dict(),
"max": df.max().to_dict()
}
To work with Pandas in Chaquopy, use the lightweight version: pip install pandas==1.3.5 (newer versions may not be supported).
7. Alternative tools: BeeWare, QPython, Pydroid
In addition to Chaquopy and Python for Android, there are other tools for integrating Python into Android:
BeeWare
Framework for creating native applications in Python. Advantages:
- โ Full support Android i iOS.
- โ Uses native UI components (not WebView).
- โ ๏ธ Requires learning Toga (BeeWare GUI library).
Installation:
pip install briefcasebriefcase create
briefcase build android
briefcase run android
QPython
Python interpreter for Android, which can be embedded in applications. Suitable for: Educational applications (code editor on the device). data-i="248">A popular application for running Python on Android. Can be used as:
- ๐ Educational applications (code editor on the device).
- ๐งฉ Modular systems with plugins in Python.
Limitation: no direct integration with Android Studio - need to be connected manually libpython.so.
Pydroid 3
Popular app for running Python on Android. Can be used as:
- ๐ง External interpreter (call via
Intent). - ๐ฆ Source of ready-made libraries (copy
.so-files to your project).
| Tool | Best for | Integration complexity |
|---|---|---|
| Chaquopy | Hybrid applications with simple Python code | Low |
| Python for Android | Kivy games, complex native libraries | High |
| BeeWare | Cross-platform applications (Android + iOS) | Medium |
| QPython | Embedded code editor | Average |
8. Conclusion and recommendations for choosing a method
The choice of how to integrate Python into Android Studio depends on your tasks:
- ๐น Chaquopy โ if you need a simple and supported method for most libraries (except C extensions).
- ๐น Python for Android โ for games on Kivy or projects with full control over the assembly.
- ๐น REST API - if the logic requires server processing or high performance.
- ๐น BeeWare/QPython - for specific tasks (cross-platform or embedded editor).
For most projects Chaquopy will be the optimal choice thanks to simplicity and Google support. Start with it, and only if you encounter limitations (for example, you need the full version TensorFlow), move on to alternatives.
Do not forget to test performance on real devices - the emulator may give inaccurate results due to differences in processor architecture. Also stay tuned for Chaquopy updates: new versions add support for additional libraries.
To speed up development, use Chaquopy templates from the official repository. There are examples of working with NumPy, Matplotlib and SQLite.
FAQ: Frequently asked questions about Python in Android Studio
Can Python be used to develop full-fledged Android applications?
Yes, but with reservations. Python is suitable for:
- ๐งฎ Computational tasks (machine learning, analytics).
- ๐ Data processing (CSV, JSON, images).
- ๐ค Automation (scripts for the backend).
However for UI It is better to use native tools (Jetpack Compose or XML), since Python libraries for the interface (for example, Kivy) are less productive and do not correspond Material Design.
How to reduce the size of the APK when using Chaquopy?
Chaquopy adds ~5โ10 MB to the APK size. To reduce it:
- Use
abiFilterstobuild.gradleto collect only the necessary architectures:ndk {abiFilters 'armeabi-v7a', 'arm64-v8a'
} - Disable unnecessary Python modules via
exclude:python {exclude "tkinter", "test"
} - Use ProGuard to remove unused code (enable in
build.gradle:minifyEnabled trueshrinkResources true
Is it possible to debug Python code directly in Android Studio?
Yes, Chaquopy supports debugging via Python Debugger. To do this:
- Install plugin Python in Android Studio (
File โ Settings โ Plugins). - Add a breakpoint (breakpoint) in Python code.
- Run the application in debug mode (
Debug 'app'). - Use
Logcatwith filterpythonto view outputsprint().
For advanced debugging (viewing variables, step-by-step execution) connect via PyCharm by adb.
How to bypass Chaquopy's limitation on C-extensions?
If you need a library with C extensions (for example TensorFlow or SciPy), there are several workarounds:
- ๐ Use alternative libraries:
- TensorFlow Lite instead of the full one TensorFlow.
- NumPy instead SciPy (partial replacement).
- ๐ Place the logic on the server (see Method 3).
- ๐ ๏ธ Build the library yourself using NDK and connect as a native module.
For TensorFlow Google recommends using TensorFlow Lite with Chaquopy or MediaPipe for computer vision tasks.
Where to store machine learning models for Python in Android?
Models (for example, .tflite or .h5) can be stored in:
- ๐ Folder
assetsโmodels will be packaged in APK. Suitable for small files (<10 MB). - ๐ฅ๏ธ External storage (
getExternalFilesDir()) - for large models downloaded after installation. - โ๏ธ Cloud (Firebase, S3) - models are downloaded on demand.
Example of loading a model from assets:
// Kotlinval modelFile = File(cacheDir, "model.tflite")
if (!modelFile.exists()) {
assets.open("model.tflite").use { input ->
modelFile.outputStream().use { output ->
input.copyTo(output)
}
}
}
In Python code, specify the path to the copied file:
interpreter = tflite.Interpreter(model_path=modelFile.absolutePath)