首先贴上官方的地址: BeeWare 教程
其中的安装和初始化过程在上一片有描述,这张介绍一些基础使用:
1. 多文件开发支持
通常一个工程下我们通常会分为多个 app进行开发,例如如下目录:

如果我们按照一般的引入方法:
会出现找不到模块错误,这里看下官方的解释issues;
也就是以下几步骤:
- 在目录下创建
__init__.py; - 导入方式:
from logfileprocess.tools.webrtc_log import extract_objc_lines_from_logs,然后就可以按照正常的方式使用了
2. java和Python交互
java调用python
BeeWare使用的是chaquopy和Java进行交互(我还是认为Jep - Java Embedded Python的交互方式比较好,当然BeeWare选择这个,那就用这个也是可以),其文档地址,;初始化完BeeWare后就会自动在Python环境和Java环境配置好chaquopy相关的配置,这里我们直接看一个简单的调用:
- 在app.py中新增如下代码:
def hello_python(str):
print(u"Hello, Python({})!!!!!!".format(str))
2.在Java的MainActivity中新增
py.getModule("logfileprocess.app").callAttr(
"hello_python","sdcard/0/logfileprocess"
);
关于chaquopy的Python对象创建,这里在后面分析源码的时候说,具体的可以看原文实现;
然后在命令行执行:
briefcase build android -r
在实际测试的时候如果不加-r,Python修改的代码不会同步;
接着执行
briefcase run android
在控制台就是输出:

这里看到我们从Java传递的参数在Python中输出了
python调用java
这里直接使用MainActivity类做示范:
现在类中增加方法:
public static void onPthonCallback(String msg){
Log.d("MainActivity 这是来及Java--》",msg);
}
python中调用:
首先引入# 调用 Java 的 Android API 示例
from java import jclass
调用Java方法:
# 获取 Java 类
MyJavaClass = jclass('org.beeware.android.MainActivity')
# 创建类的实例
my_java_object = MyJavaClass()
# 调用 Java 方法
my_java_object.onPthonCallback("John")
输出结果:

其他类
这里使用自定义的Java类,然后在Python中调用,Java类的定义如下:
package org.beeware.android;
public class ProcessLogFile {
static private ProcessLogFile instance;
// 定义一个接口用于回调
public interface OnPythonCallbackListener {
void onPythonCallback(String msg);
}
// 接口的实例
private final OnPythonCallbackListener callbackListener;
// 构造方法,接受接口实现的对象
public ProcessLogFile(OnPythonCallbackListener listener) {
instance = this;
this.callbackListener = listener;
}
public void onPthonCallback(String msg){
// 确保 UI 更新在主线程中进行
// 调用回调方法将消息传递给 MainActivity
if (callbackListener != null) {
callbackListener.onPythonCallback(msg);
}
}
public static ProcessLogFile getInstance(){
return instance;
}
}
这里使用static private ProcessLogFile instance;的方式,是为了在Python中不用再new一个对象,和Java中的对象保持一致;
其中的 public void onPthonCallback(String msg)是Python中调用,只有单例模式,才能保持一个对象,从而在设置回调监听的类里面才能拿到ProcessLogFile回调接口的数据;
Python中调用Java接口:
def isAndroid():
if plt == "Windows":
# print("Your system is Windows")
return False
# do x y z
elif plt == "Linux":
print("Your system is Linux")
if "ANDROID_BOOTLOGO" in environ:
# print("====================>Running on Android")
return True
else:
# print("Not Android OS")
return False
# do x y z
elif plt == "Darwin":
# print("Your system is MacOS")
return False
# do x y z
else:
# print("Unidentified system")
return False
def process_log_queue_(message):
if isAndroid():
# 获取Java对应的类
ProcessLogFile = jclass("org.beeware.android.ProcessLogFile")
# 调用静态方法获取 processLogFile 实例对象
my_java_object = ProcessLogFile.getInstance()
# 创建类的实例 Java中使用单例的方式 就是避免这里又要new一个对象
# my_java_object = MyJavaClass()
print("------>" + message)
# 调用 Java 方法
my_java_object.onPthonCallback(message)
else:
# global log_messages
# log_messages.append(msg) # 将消息添加到日志列表
update_log_view(message) # 更新日志视图
print("------>" + message)
Python中主线程调用
这里使用定时器定时从队列中取出消息转发的机制;
- 定义queue
# 创建一个线程安全的队列,用于在后台线程与主线程间传递日志消息
log_queue = queue.Queue()
- 将消息放入队列的方法
def send_msg_toJava(msg):
log_queue.put(msg)
- 定义定时器和执行方法
# 定时器,每隔一段时间执行一次
def start_processing_log_queue():
loop = asyncio.get_event_loop()
loop.create_task(process_log_queue()) # 启动日志处理任务
async def process_log_queue():
while True:
# 如果队列不为空,获取并处理消息
if not log_queue.empty():
message = log_queue.get()
if message:
process_log_queue_(message) # 更新日志视图
await asyncio.sleep(0.03) # 每 30ms 检查一次队列
最后的process_log_queue_方法中调用Java的方法就基本能保证是在主线程调用
补充一种简单调用
使用 add_background_task,确保 process_log_queue_ 在主线程中调用
toga.App.app.add_background_task(lambda app: process_log_queue_(message))
主要命令
- MacOS等桌面平台可以直接使用
briefcase dev运行,打包使用:
briefcase package macOS
或者使用
briefcase build macos xcode
这个会生成一个xcode工程,双击打开后就可以使用xcode打包
- 移动端,Android为例子如下:
- 编译使用
briefcase build android -r或briefcase build android,这两个的差别实际测试中,不加-r不会编译Python的修改,只会编译Android的修改代码; - 运行执行
briefcase run android,然后选择执行真机还是模拟器即可;也可以直接使用adb命令安装build目录下的apk
macos上其他问题
使用pyenv管理Python版本
由于briefcase是Python3的,所以为了便于管理Python版本这里使用pytnv安装Python3:
pyenv在 macOS 11 (Apple Silicon) 上安装
在 macOS 上安装有两种方法pyenv:
- 通过Homebrew:这是最快的方法。但是,无法
pyenv在 macOS 11(Apple Silicon)上安装; - 直接编译 Git checkout:pyenv团队已在README中详细记录了安装过程。但是,当我按照步骤一步步操作并应用于我的新 macOS 11 (M1) 时,最终没有起作用。经过几个小时的调整,以下是我设法使其与 Git check out 安装配合使用的方法。
- 将 repo克隆pyenv到你的主文件夹中:
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
cd ~/.pyenv && src/configure && make -C src
- 编辑.
zshrc并在文件底部添加以下几行(macOS 11 自带 zsh 作为默认 shell)
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
-
退出终端并重新打开。现在pyenv已经安装成功。使用方式如下:
- 查看 pyenv 已经管理了哪些 python 版本
pyenv versions- 使用pyenv安装指定的Python版本
pyenv install -v 3.12.3 pyenv install -v 2.7.13- 把Python切换到指定版本
pyenv global 3.12.3- 查看系统当前python版本
python输出
Python 3.8.9 (default, Jun 23 2021, 14:45:36)
* 查看pyenv当前支持哪些Python版本
```bash
pyenv install --list
```
1. urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl’ module is compiled with 'OpenSSL 1.0.2r
如果遇到这个问题,需要重新执行以下步骤:
- 升级openssl,执行
brew reinstall openssl@1.1
然后将这个添加到.zshrc环境中:
echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
接着执行:
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
上面三个是将连接的库指向OpenSSL1.1
2. 安装低版本的
pip install urllib3==1.26.6
如果还报错重装Python3的:
pip3 install urllib3==1.26.6
2. 如果遇到pkg_resources.VersionConflict: (wheel 0.33.0 (/usr/local/lib/python3.7/site-packages), Requirement.parse(‘wheel>=0.34’))
执行:
pip3 install --upgrade wheel
3. 提示缺失Model
执行:
pip3 install toga
pip3 install matplotlib
pip3 install --pre toga
3047

被折叠的 条评论
为什么被折叠?



