如何在Android/iOS设备后台启动Flask服务器(Flutter+Python架构)
在Android/iOS设备上同时启动Flutter应用与本地Flask服务器
要实现Flutter前端和本地Flask服务器在移动设备上离线协同运行,核心是将Python运行环境嵌入移动端应用,并通过Flutter与原生平台的通信触发服务器启动。以下是分平台的具体实现方案:
Android 端实现
1. 集成 Chaquopy 运行 Python
Chaquopy 是 Android 平台上的 Python 嵌入框架,能直接将 Python 代码和依赖打包进 APK。
- 在项目根目录的
android/build.gradle中添加 Chaquopy 依赖:
buildscript { repositories { maven { url "https://chaquo.com/maven" } } dependencies { classpath "com.chaquo.python:gradle:14.0.2" } }
- 在
android/app/build.gradle中应用插件并配置 Python 环境:
apply plugin: "com.chaquo.python" android { defaultConfig { ndk { abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } python { srcDir "../../python" // 指定你的Flask代码所在目录 pip { install "flask" "paramiko" // 安装所需Python依赖 } } } }
2. 原生代码启动 Flask 服务器
在 Android 的 MainActivity 中通过 MethodChannel 接收 Flutter 的启动指令,在后台线程启动服务器:
import com.chaquo.python.Python import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "com.your_app_name/flask_server" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> if (call.method == "startServer") { Thread { try { val python = Python.getInstance() python.getModule("server") // 你的Flask代码文件名为server.py result.success("Flask server started on port 5000") } catch (e: Exception) { result.error("START_FAILED", e.message, null) } }.start() } else { result.notImplemented() } } } }
iOS 端实现
1. 集成 PythonKit 运行 Python
PythonKit 是 Swift 与 Python 交互的库,需搭配预编译的 iOS Python 框架使用。
- 在 iOS 项目的
Podfile中添加依赖:
pod 'PythonKit'
执行 pod install 完成安装。
- 将预编译的
Python.framework导入项目,并把你的 Flask 代码(server.py)及依赖包复制到项目的 Resources 目录下(需提前在本地安装依赖,复制site-packages中的相关文件)。
2. 原生代码启动 Flask 服务器
在 AppDelegate.swift 中通过 MethodChannel 处理 Flutter 的启动请求,在后台线程启动服务器:
import Flutter import PythonKit @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private let CHANNEL = "com.your_app_name/flask_server" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { guard let controller = window?.rootViewController as? FlutterViewController else { return super.application(application, didFinishLaunchingWithOptions: launchOptions) } let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard call.method == "startServer" else { result.notImplemented() return } DispatchQueue.global(qos: .background).async { let sys = Python.import("sys") if let pythonPath = Bundle.main.path(forResource: "python", ofType: nil) { sys.path.append(pythonPath) } let server = Python.import("server") server.app.run(host: "0.0.0.0", port: 5000) } result.success("Flask server started on port 5000") } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
Flutter 端触发服务器启动
在 Flutter 的 main 函数中,初始化时通过 MethodChannel 调用原生代码启动服务器:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); const platform = MethodChannel('com.your_app_name/flask_server'); try { final String response = await platform.invokeMethod('startServer'); print(response); } on PlatformException catch (e) { print("Server start failed: ${e.message}"); } runApp(const MyApp()); }
关键注意事项
- 权限配置:
- Android:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.INTERNET"/> - iOS:在
Info.plist中添加允许本地网络请求的配置:<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsLocalNetworking</key> <true/> </dict>
- Android:在
- 网络访问:Flutter 应用通过
http://127.0.0.1:5000访问本地 Flask 服务器 - 线程处理:必须将 Flask 的
run方法放在后台线程,避免阻塞 UI 线程
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

