Android修行手冊-集成Python開發環境

Unity3D特效百例案例項目實戰源碼Android-Unity實戰問題匯總
游戲腳本-輔助自動化Android控件全解手冊再戰Android系列
Scratch編程案例軟考全系列Unity3D學習專欄
藍橋系列ChatGPT和AIGC

👉關于作者

專注于Android/Unity和各種游戲開發技巧,以及各種資源分享(網站、工具、素材、源碼、游戲等)
有什么需要歡迎底部卡片私我,交流讓學習不再孤單

在這里插入圖片描述

👉實踐過程

😜前言

出于業余興趣,我幾年前一直想研究關于Python移植到Android上的實現方案,就像JNI開發一樣真正的在Andorid中進行混合Python編程。但出于上班忙時間少,加上人生大事精力有限,人的惰性等等原因,一直沒有深入探索,直到2024年有項目需要集成Python,就準備查詢下資料,發現已經有人做了我一直想做的事,而且已經做得比較完善了,更可喜的是思路大體一致。

真是應了那句話:你能想到的東西,世界上一定已經存在了,只不過你還沒見到而已。

支持AGP版本和Python運行版本
在這里插入圖片描述

😜配置環境

首先你需要確保已經安裝好了Python環境,并且環境變量也配置好了,Python 的安裝包可以一鍵幫我們都處理好,只需要你仔細看清安裝彈框中的說明做好勾選即可。

gradle的版本不同,build.gradle中的寫法不同,讀者根據自己的環境做好對應。

找到工程目錄的 build.gradle

buildscript { //寫法一repositories {google()maven { url 'https://jitpack.io' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases/' }maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }maven { url 'https://maven.aliyun.com/repository/google' }maven { url 'https://maven.aliyun.com/repository/public' }maven { url 'https://maven.aliyun.com/repository/jcenter' }maven { url "https://chaquo.com/maven" } //python插件的地址 mavenCentral()}dependencies {classpath("com.android.tools.build:gradle:7.0.2")classpath "com.chaquo.python:gradle:15.0.1" //python插件的版本,盡量用新的,支持的內容多 也修復了很多問題
//        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"}
}
task clean(type: Delete) {delete rootProject.buildDir
}
plugins { //寫法二id 'com.android.application' version '8.0.2' apply falseid 'org.jetbrains.kotlin.android' version '1.6.21' apply falseid 'com.chaquo.python' version '15.0.1' apply false   //這個是重點
}task clean(type: Delete) {delete rootProject.buildDir
}

具體項目的 build.gradle

plugins {id 'com.android.application'id 'com.chaquo.python'  //集成python必備
}android {compileSdk 32defaultConfig {applicationId "com.example.myapplication"minSdk 26targetSdk 32versionCode 1versionName "1.0"ndk {abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"}python {buildPython "D:\\Program Files\\Python\\python.exe" //不同的人電腦環境不同pip {install "matplotlib"  //如果想要安裝三方包
//                // 需求說明符,帶或不帶版本號:
//                install "scipy"
//                install "requests==2.24.0"
//                // 相對于項目目錄的sdist或wheel文件名:
//                install "MyPackage-1.2.3-py2.py3-none-any.whl"
//                // 包含setup.py的目錄,相對于項目
//                // 目錄(必須包含至少一個斜杠):
//                install "./MyPackage"
//                // "-r" '后面跟著一個需求文件名,相對于
//                // 項目目錄:
//                install "-r", "requirements.txt"}}testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation 'androidx.appcompat:appcompat:1.3.0'implementation 'com.google.android.material:material:1.4.0'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
}

在這里插入圖片描述

工程下的 setting.gradle

//開發andorid的都知道 gradle 配置的寫法 變動的很大 下方的設置看需要和你的當下項目是否類似再寫。
pluginManagement {repositories {google()maven { url 'https://jitpack.io' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases/' }maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }maven { url "https://chaquo.com/maven" } //確保這個地址mavenCentral()}plugins {id 'com.android.application' version '7.1.0-alpha11'id 'com.android.library' version '7.1.0-alpha11'id 'org.jetbrains.kotlin.android' version '1.6.21'}
}
dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)repositories {google()maven { url 'https://jitpack.io' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases/' }maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }maven { url "https://chaquo.com/maven" } //確保這個地址mavenCentral()}
}
rootProject.name = "My Application"
include ':app'

😜代碼實戰

代碼要寫在具體項目的 main 目錄的 python 文件夾。
在這里插入圖片描述
Python中代碼

from java import jclass
def sayHello():print("這是一個測試")def greet(name):print("--- hello,%s ---" % name)def add(a,b):return a + bdef sub(count,a=0,b=0,c=0):return count - a - b -cdef get_list(a,b,c,d):return [a,b,c,d]def print_list(data):print(type(data))# 遍歷Java的ArrayList對象for i in range(data.size()):print(data.get(i))# python調用Java類
def get_java_bean():JavaBean = jclass("org.hello.JavaBean")  # 實體類的類名jb = JavaBean("python")jb.setData("json")jb.setData("xml")jb.setData("xhtml")return jb

Java中代碼
核心思想便是對象轉換,PyObject類是橋梁,fromJava函數將一個Java對象轉換為相應的Python對象,toJava函數正好相反,將Python中的對象轉換成Java中的對象

public class TestPython extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_python);if (!Python.isStarted()) {Python.start(new AndroidPlatform(this));  //可以放到app里進行初始化}Python python = Python.getInstance();PyObject pyObject = python.getModule("hello");  //調用的文件名pyObject.callAttr("sayHello"); //調用的方法名Python py = Python.getInstance();// 調用hello.py模塊中的greet函數,并傳一個參數// 等價用法:py.getModule("hello").get("greet").call("Android");py.getModule("hello").callAttr("greet", "Android");// 調用python內建函數help(),輸出了幫助信息py.getBuiltins().get("help").call();PyObject obj1 = py.getModule("hello").callAttr("add", 2,3);// 將Python返回值換為Java中的Integer類型Integer sum = obj1.toJava(Integer.class);Log.d("TAG","add = "+sum.toString());// 調用python函數,命名式傳參,等同 sub(10,b=1,c=3)PyObject obj2 = py.getModule("hello").callAttr("sub", 10,new Kwarg("b", 1), new Kwarg("c", 3));Integer result = obj2.toJava(Integer.class);Log.d("TAG","sub = "+result.toString());// 調用Python函數,將返回的Python中的list轉為Java的list   也可以使用mapPyObject obj3 = py.getModule("hello").callAttr("get_list", 10,"xx",5.6,'c');List<PyObject> pyList = obj3.asList();Log.d("TAG","get_list = "+pyList.toString());// 將Java的ArrayList對象傳入Python中使用List<PyObject> params = new ArrayList<PyObject>();params.add(PyObject.fromJava("alex"));params.add(PyObject.fromJava("bruce"));py.getModule("hello").callAttr("print_list", params);// Python中調用Java類PyObject obj4 = py.getModule("hello").callAttr("get_java_bean");JavaBean data = obj4.toJava(JavaBean.class);data.print();Python pyTe = Python.getInstance(); //matplotlib庫的方法PyObject module = pyTe.getModule("plot"); //文件名byte[] dddz = module.callAttr("plot", "1 2 3 4", "1 2 3 4").toJava(byte[].class);ImageView img = findViewById(R.id.testImg);img.setImageBitmap(BitmapFactory.decodeByteArray(dddz, 0, dddz.length));}
}
  • Python.getInstance():獲取Python運行環境,映射為Java中的Python;
  • py.getModule:執行指定的Python文件,映射為Java中的PyObject;
  • module.callAttr:執行Python文件中指定的方法,并傳遞參數,返回PyObject對象;

kotlin代碼自行轉換即可。

😜原理

簡單說就是以android的JNI技術為橋梁,JNI技術解決了Java與C/C++混合編程的問題,而Python官方解釋器則是純C語言實現的,名為CPython解釋器,在Android上,Python解釋器就是一個so動態庫。JNI接口使得C語言能反射Java的類與方法,而Python運行在C語言之上,那么Python也就具備了調用Java的能力。整個過程就是Java調用C語言代碼,C再調用CPython解釋器從而執行Python代碼;Python調用CPython解釋器,CPython調用C語言代碼,C語言代碼再反射Java代碼,完成一次反調。這之間,粘合Java與CPython解釋器的一段C語言代碼,也就是Chaquopy框架干的事。
在這里插入圖片描述

😜可能得問題

  1. 當你剛配置好環境第一次運行了 python 的 hello word 后,就開始蠢蠢欲動準備搞一搞集成三方庫。可以當你在 build.gradle 中配置好 pip 一運行,發現有可能出現下面的問題:
    Process ‘command ‘C:\Users\Administrator\AppData\Local\Programs\Python\Python312\python.exe’’ finished with non-zero exit value 1
    靜下心來好好想想,區別就在 pip 安裝三方庫上,Android 上既然是 Chaquopy 遠程安裝那么就得往該插件上考慮。在整個過程中我們的配置只有兩個地方是可變動的,
    一個是 python 的安裝路徑,一個是 Chaquopy 的版本號。本地安裝路徑如果和配置不一致,不是這個錯誤。那么只有一個問題,就是 Chaquopy 的版本。
    我們切換最新的試試,發現解決了。
  2. Chaquopy 不是支持所有的三方庫,這是最難搞的事情。具體可從這查看。點擊跳轉
  3. 還可以實現 Python 自動生成 Java的類,但是該功能用處不大,想要了解的可自行搜索靜態代理。
  4. Chaquopy是線程安全的。但是,因為它基于CPython(Python參考實現),所以它受到CPython的全局解釋器鎖(GIL)的限制。這意味著盡管Python代碼可以在任意數量的線程上運行,但在任何給定時刻只會執行其中一個線程。
  5. 如果Python對象引用直接或間接引用原始Python對象的Java對象,則可以創建跨語言引用循環。任何一種語言的垃圾收集器都無法檢測到這樣的循環。所以避免內存泄漏很重要。Python代碼就需要寫的很合理。

👉其他

📢作者:小空和小芝中的小空
📢轉載說明-務必注明來源:https://zhima.blog.csdn.net/
📢這位道友請留步??,我觀你氣度不凡,談吐間隱隱有王者霸氣💚,日后定有一番大作為📝!!!旁邊有點贊👍收藏🌟今日傳你,點了吧,未來你成功??,我分文不取,若不成功??,也好回來找我。

溫馨提示點擊下方卡片獲取更多意想不到的資源。
空名先生

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713467.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713467.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713467.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Debezium發布歷史161

原文地址&#xff1a; https://debezium.io/blog/2023/09/13/debezium-2-4-beta2-released/ 歡迎關注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻譯&#xff0c;僅供參考&#xff0c;筆芯筆芯. Debezium 2.4.0.Beta2 Released September 13, 2023 by Chris Cranfo…

Apache Flink連載(三十五):Flink基于Kubernetes部署(5)-Kubernetes 集群搭建-1

?? 個人主頁:IT貧道-CSDN博客 ?? 私聊博主:私聊博主加WX好友,獲取更多資料哦~ ?? 博主個人B棧地址:豹哥教你學編程的個人空間-豹哥教你學編程個人主頁-嗶哩嗶哩視頻 目錄 ?編輯

Python爬蟲——Urllib庫-2

編解碼 問題引入 例如&#xff1a; https://www.baidu.com/s?wd章若楠 https://www.baidu.com/s?wd%E7%AB%A0%E8%8B%A5%E6%A5%A0 第二部分的一串亂碼就是章若楠 如果這里是寫的章若楠就會 產生這樣的錯誤 所以我們就可以使用get請求方式的quote方法了 get請求方式的q…

laravel ApiResponse接口統一響應封裝

一&#xff0c;新增接口返回碼配置文件 在config中新增配置文件apicode.php <?phpreturn [ apicodes>[/*** Message("OK")* 對成功的 GET、PUT、PATCH 或 DELETE 操作進行響應。也可以被用在不創建新資源的 POST 操作上*/HTTP_OK > 200,/*** Message(&qu…

使用el-form之表單校驗自動定位到報錯位置問題,,提升用戶體驗

需求描述 由于需要填寫的表單項太多&#xff0c;提交的時候校驗不通過&#xff0c; 如果沒填寫的表單項在最上面&#xff0c;用戶看不到不知道發生了啥&#xff0c; 所以需要將頁面滾動定位到第一個報錯的表單項位置&#xff0c;提升用戶體驗實現步驟 1. 給form表單添加ref …

數據中心GPU集群高性能組網技術分析

數據中心GPU集群組網技術是指將多個GPU設備連接在一起&#xff0c;形成一個高性能計算的集群系統。通過集群組網技術&#xff0c;可以實現多個GPU設備之間的協同計算&#xff0c;提供更大規模的計算能力&#xff0c;適用于需要大規模并行計算的應用場景。 常用的組網技術&…

1209. 帶分數 刷題筆記

思路 暴力匹配 讀入目標數 n 看n是否與ab/c相等 因為c里面的除法是整除 我們將 nab/c 轉換為 c*na*cb 那么如何獲得a,b&#xff0c;c 依題意 a&#xff0c;b&#xff0c;c三個數由1-9九個數字組成 且每個數字只能出現一次 由此 我們可以搜出123456789的全部排列方式…

我做的app上架應用市場一天,快破400下載量,0差評

上集說到&#xff0c;我做了一個叫QB音樂的安卓app&#xff0c;經過一段時間的自我使用與測試終于算發布了。我昨天順便把它上架了奇妙應用市場&#xff0c;截止目前3月1號過去了一天&#xff0c;下載量快到400&#xff0c;0差評。看來還是能正常使用的。 一、為什么做這個ap…

CleanMyMac X2024免費Mac電腦清理和優化工具

CleanMyMac X是一款專業的 Mac 清理和優化工具&#xff0c;它具備一系列強大的功能&#xff0c;可以幫助用戶輕松管理和維護他們的 Mac 電腦。以下是一些關于 CleanMyMac X 的主要功能和特點&#xff1a; 智能清理&#xff1a;CleanMyMac X 能夠智能識別并清理 Mac 上的無用文件…

深入剖析k8s-Pod篇

為什么需要Pod&#xff1f; 進程是以進程組的方式組織在一起。受限制容器的“單進程模型”&#xff0c; 成組調用沒有被妥善處理&#xff08;資源調用有限&#xff09;&#xff0c;使用資源囤積則導致復雜度上升。 在k8s項目中&#xff0c;Pod的實現需要使用一個中間容器——…

css【詳解】—— 圣杯布局 vs 雙飛翼布局 (含手寫清除浮動 clearfix)

兩者功能效果相同&#xff0c;實現方式不同 效果預覽 兩側寬度固定&#xff0c;中間寬度自適應&#xff08;三欄布局&#xff09;中間部分優先渲染允許三列中的任意一列成為最高列 圣杯布局 通過左右欄填充容器的左右 padding 實現&#xff0c;更多細節詳見注釋。 <!DOCTYP…

《無線網絡技術》考試版筆記

第一章 無線網絡介紹 什么是多徑效應&#xff0c;如何去克服&#xff1a; 在發射機和接收機之間沒有明顯的直線路徑時&#xff0c;就會產生多徑傳播。如果兩個信號彼此疊加&#xff0c;那么接收設備就無法正確解調信號&#xff0c;無法還原為它的原始數據形式。 可以稍微調整接…

【leetcode熱題】求根到葉子節點數字之和

難度&#xff1a; 中等通過率&#xff1a; 40.6%題目鏈接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 題目描述 給定一個二叉樹&#xff0c;它的每個結點都存放一個 0-9 的數字&#xff0c;每條從根到葉子節點的路徑都代表一個數字。 例如&#xff0c;從根到葉子…

Linux包管理dpkg、apt和snap

dpkg、apt和snap都是Ubuntu系統中用于軟件管理的工具&#xff0c;但它們在功能和使用上有一些區別。 dpkg: dpkg是Debian包管理系統的底層工具&#xff0c;也是apt和其他高級包管理工具的基礎。主要功能是用于安裝、卸載、配置和構建Debian軟件包&#xff08;.deb文件&#xff…

vue面試題:Computed 和 Watch 的區別?

Computed 和 Watch 的區別? 對于Computed&#xff1a;對于Watch&#xff1a;immediate&#xff1a;組件加載立即觸發回調函數deep&#xff1a;深度監聽&#xff0c;發現數據內部的變化&#xff0c;在復雜數據類型中使用&#xff0c;例如數組中的對象發生變化。需要注意的是&am…

USLE模型-LS因子的計算

目錄 計算坡度計算填洼計算流向計算水流長度計算水平投影![在這里插入圖片描述](https://img-blog.csdnimg.cn/direct/75e015b2d6874ce9b6652f2b8730b90f.png)計算可變的坡度指數m計算坡長因子L計算坡度因子S計算LS因子參考視頻 計算坡度 準備好30米分辨率的dem 計算填洼 計…

速看!深夜悄悄分享一個電力優化代碼集合包!

代碼集合包如下&#xff1a; 主從博弈的智能小區定價策略及電動汽車調度策略 碳交易機制下的綜合能源優化調度 兩階段魯棒優化算法的微網多電源容量配置 冷熱電多能互補綜合能源系統優化調度 考慮預測不確定性的綜合能源調度優化 考慮柔性負荷的綜合能源系統低碳經濟優化調度 考…

MySQL深入——24

Join語句到底可不可用 join語句用于兩個或多個表當中檢索數據。 INNER JOIN或者JOIN 當兩個表當中有匹配的值時&#xff0c;返回行 LEFT JOIN或者LEFT OUTER JOIN 返回所有左邊的行&#xff0c;即使右表當中沒有相匹配的行 RIGHT JOIN或者RIGHT OUTER JOIN 返回所有右邊的…

整數的分離與合成

整數是由數字和數位組成的&#xff0c;比如327是一個三位數&#xff0c;它的數字是3、2、7,數位是個數、十位、百位。 經常有些題目考查將一個整數拆分成各個數字&#xff0c;以及將各個數字合成一個整數&#xff0c;下面分別就此討論。 注&#xff1a;只考慮正整數&#xff…

C語言學生成績信息管理系統【結構體+文本】

功能描述&#xff1a; 1、錄入成績 2、顯示不及格學生信息 3、統計每檔學生數量 4、總成績統計 代碼&#xff1a; #include<stdio.h>#define N 30//結構體&#xff1a;typedef struct STUDENT{char id[10];//學號char name[20];//姓名float score[3];//三門成績,分別代…