Chaquopy: Usando Python em Aplicativos Android
Python é uma das linguagens mais populares na comunidade de desenvolvedores devido à sua simplicidade, robustez e um grande ecossistema de pacotes que o tornam super útil em vários domínios. O uso de pacotes como NumPy e SciPy permite que os programadores executem facilmente operações matemáticas de alto nível que, de outra forma, não estariam disponíveis em outras linguagens de programação. Que tal trazer o poder do Python para aplicativos Android?
Chaquopy é uma estrutura que pode ajudar os desenvolvedores a executar scripts Python a partir do código Java/Kotlin em aplicativos Android. Ao contrário de outras bibliotecas multilíngue, não há problemas de NDK ou código nativo e a instalação é fácil. Nesta história, exploraremos o Chaquopy, sua arquitetura e uso com código Kotlin.
Conteúdo
- O que é o Chaquopy e como ele usa o Python no Android?
- Adicionando Chaquopy em seu projeto Android
- Usando objetos Python do código Java/Kotlin
- Recursos
Assim como funciona a maioria das interfaces entre linguagens, Python e Android têm um ancestral comum de C/C++ que pode permitir que eles se comuniquem em um meio comum. O NDK do Android permite que os desenvolvedores usem bibliotecas nativas (escritas em C/C++) em um aplicativo Android, o que é ótimo para gráficos de alto desempenho e computação científica.
Chaquopy usa CPython, uma implementação de Python escrita em linguagem C. Ao contrário do equívoco comum, o Python não é uma linguagem puramente interpretada. O código-fonte do Python é primeiro compilado para um bytecode especial que é então interpretado pelo CPython. CPython é apenas uma das várias implementações de Python, outras incluem PyPy, IronPython, Jython etc.
A equipe do Chaquopy cria o CPython com a cadeia de ferramentas NDK do Android. O CPython é baixado do repositório Maven Central pelo plug-in Gradle do Chaquopy durante a construção do projeto e os usuários não precisam baixar o NDK para o processo. Ele também baixa os tempos de execução do Chaquopy, que faz a interface do código Java/Kotlin com o Python por meio do JNI.
Enquanto isso, também precisaríamos do gerenciador de pacotes do Python pip, que pode baixar pacotes para o interpretador. Pacotes populares gostam NumPye SciPyusam código nativo para executar cálculos intensivos de CPU, que precisam ser compilados antes da instalação. Portanto, a equipe Chaquopy mantém seus próprios repositórios com pacotes nativos criados especificamente para a arquitetura ARM do Android. Os mantenedores desses pacotes não constroem seu código nativo para o destino Android, devido a um número menor de usuários, portanto, a equipe Chaquopy os cria para o destino Android e os distribui por meio de seu próprio repositório.
Para pacotes Python puros, nenhuma construção externa é necessária e o interpretador do Chaquopy pode executá-los diretamente. Para uma visão geral de alto nível, o Chaquopy contém três componentes principais:
- Chaquopy Gradle Plugin
- Chaquopy Tempo de Execução
- Repositório de Pacotes
1.1. Dependências Gradle e especificações ABI
Para adicionar Chaquopy em seu projeto Android novo/existente, vá para o script de nível de projeto build.gradle, onde definimos plug-ins Gradle para o projeto e adicione o plug-in Gradle do Chaquopy,
plugins {
id 'com.android.application' version '7.3.0' apply false
id 'com.android.library' version '7.3.0' apply false
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
id 'com.chaquo.python' version '13.0.0' apply false
}
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.chaquo.python'
}
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
}
}
...
}
O comportamento padrão do sistema de compilação é incluir os binários para cada ABI em um único APK, também conhecido como APK gordo . Um APK gordo é significativamente maior do que um contendo apenas os binários para uma única ABI; a compensação está ganhando compatibilidade mais ampla, mas às custas de um APK maior. É altamente recomendável que você aproveite os App Bundles ou APK Splits para reduzir o tamanho de seus APKs e, ao mesmo tempo, manter a compatibilidade máxima do dispositivo.
1.2. Versão Python e pacotes PIP
Em seguida, configuraremos a versão do Python que deve ser construída. Podemos especificar isso modificando o nível do módulo build.gradle,
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.chaquo.python'
}
android {
...
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
}
python {
version "3.8"
}
}
...
}
defaultConfig {
python {
pip {
// A requirement specifier, with or without a version number:
install "scipy"
install "requests==2.24.0"
// An sdist or wheel filename, relative to the project directory:
install "MyPackage-1.2.3-py2.py3-none-any.whl"
// A directory containing a setup.py, relative to the project
// directory (must contain at least one slash):
install "./MyPackage"
// "-r"` followed by a requirements filename, relative to the
// project directory:
install "-r", "requirements.txt"
}
}
}
2. Usando objetos Python do código Java/Kotlin
Em Python, usamos funções ou membros de dados que pertencem a um módulo Python, que é um .pyarquivo que contém o código-fonte. Para usar qualquer membro de um módulo Python, o primeiro passo é colocar o código-fonte Python no <project>/app/src/main/pythondiretório.
# Contents of my_module.py
import numpy as np
def get_exec_details():
return __file__
def sumOp( nums ):
return sum( nums )
def powOp( a , x ):
return a**x
def npMatrixSum( m , n ):
mat = np.ones( ( m , n ) )
mat_sum = np.sum( mat , axis=1 )
return mat_sum
class Operations:
num_ops = 2
def meanOp( self , nums ):
return sum( nums ) / len( nums )
def maxOp( self , nums ):
return max( nums )
nums_len = 10
nums_len_str = "ten"
ops = Operations()
Location of the Python module relative to the Android project and its contents. Image Source: Image by author
class App : Application() {
override fun onCreate() {
super.onCreate()
if( !Python.isStarted() ) {
Python.start( AndroidPlatform( this ) )
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".App"
...
</application>
</manifest>
val py = Python.getInstance()
val module = py.getModule( "my_module" )
Para usar um membro de dados, como nums_lenem my_module.py,
val numsLength = module[ "nums_len" ]?.toInt()
println( "Nums Length is $numsLength" )
Nums Length is 10
val ops = module[ "ops" ]!!
println( "Operations: $ops" )
println( "num_ops : ${ ops[ "num_ops" ] }" )
println( "mean func : ${ ops[ "meanOp" ] }" )
Operations: <my_module.Operations object at 0xb9339ce8>
num_ops : 2
mean func : <bound method Operations.mean of <my_module.Operations object at 0xb9339ce8>>
moduleComo uma função é um objeto em Python, é permitido acessar funções como valores de the . Em seguida, usamos PyObject.callo método para passar argumentos para uma função e obter os resultados (se a função retornar um valor)
val sumFunc = module[ "sumOp" ]
val sum = sumFunc?.call( intArrayOf( 12 , 25 , 32 ) )
val powFun = module[ "powOp" ]
val pow = powFun?.call( 5 , 2 )
println( "Sum: $sum" )
println( "Pow: $pow" )
Sum: 69
Pow: 25
val meanFunc = ops[ "meanOp" ]
val mean = meanFunc?.call( intArrayOf( 23 , 45 , 12 , 91 ) )
println( "Mean: $mean" )
// OR
val mean = ops.callAttr( "meanOp" , intArrayOf( 23 , 45 , 12 , 91 ) )
println( "Mean: $mean" )
Mean: 42.75
# my_module.py
import numpy as np
def npMatrixSum( m , n ):
mat = np.ones( ( m , n ) )
mat_sum = np.sum( mat , axis=1 )
return mat_sum
val npSumFunc = module[ "npMatrixSum" ]
val output = npSumFunc?.call( 2 , 3 )
// OR
val output = module.callAttr( "npMatrixSum" , 2 , 3 )
println( "Output: $output" )
println( "Output shape: ${output!![ "shape" ] }")
Output: [3. 3.]
Output shape: (2,)
- Documentos oficiais do Chaquopy
- Perguntas frequentes do Chaquopy : Esta seção contém respostas para várias perguntas sobre o Chaquopy
- Demonstrações do Chaquopy no GitHub
Espero ter adicionado uma nova ferramenta à sua caixa de ferramentas de desenvolvimento Android! Chaquopy é uma ótima ferramenta com uma sintaxe elegante e instalação sem complicações. Certifique-se de usar em seu próximo projeto Android. Continue aprendendo e tenha um bom dia pela frente!





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)