Kotlin中如何提取Python进程StdOut的实时动态输出
解决方案:实时捕获Python进程动态输出
1. 配置ProcessBuilder禁用缓冲
首先要强制Python禁用输出缓冲,同时避免流合并导致的延迟:
ProcessBuilder pb = new ProcessBuilder("python3", "your_script.py"); pb.redirectErrorStream(false); // 分开处理标准输出和错误输出 // 关键:设置环境变量禁用Python缓冲 pb.environment().put("PYTHONUNBUFFERED", "1");
2. 实现实时流读取线程
动态进度条通常用\r覆盖当前行,readLine()会因无\n阻塞,需改用逐字符读取:
public class StreamGobbler implements Runnable { private InputStream inputStream; private Consumer<String> outputHandler; public StreamGobbler(InputStream inputStream, Consumer<String> outputHandler) { this.inputStream = inputStream; this.outputHandler = outputHandler; } @Override public void run() { try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { char[] buffer = new char[1024]; int readLen; // 循环读取所有输出,包括带\r的动态行 while ((readLen = reader.read(buffer)) != -1) { String output = new String(buffer, 0, readLen); outputHandler.accept(output); } } catch (IOException e) { e.printStackTrace(); } } }
启动进程时同时开启两个线程分别读取标准输出和错误输出:
Process process = pb.start(); // 处理标准输出(动态进度条通常在这里) new Thread(new StreamGobbler(process.getInputStream(), output -> { // 这里处理实时输出,比如打印日志或更新UI(注意切换到主线程) Log.d("PythonLiveOutput", output); })).start(); // 处理错误输出 new Thread(new StreamGobbler(process.getErrorStream(), error -> { Log.e("PythonError", error); })).start(); // 等待进程执行完成 int exitCode = process.waitFor();
3. 验证Python脚本的输出逻辑
确保Python脚本中的进度输出强制刷新,避免脚本内部缓冲:
import sys import time for i in range(100): # 用\r覆盖当前行,同时强制刷新输出 print(f"转换进度: {i}%", end='\r', flush=True) time.sleep(0.1)
4. 注意Android线程规则
所有流读取操作必须在子线程执行,若要更新UI,需切换到主线程:
new Thread(new StreamGobbler(process.getInputStream(), output -> { runOnUiThread(() -> { // 更新UI组件,比如进度文本或进度条 progressDisplay.setText(output.trim()); }); })).start();
内容的提问来源于stack exchange,提问作者Bobby ESP
相关产品推荐
相关产品推荐

