在 Android (Kotlin) 上使用 Chaquopy 在 Python 中运行 Quart Web 服务器

问题描述 投票:0回答:1

我正在尝试使用 Chaquopy 制作一个 Android 应用程序,其中包含在 Python 上运行的 Quart 应用程序,但是一旦我从 Python 添加对 Kotlin 的调用,我就会从 MainActivity 获得

Error starting Python server: Can't create handler inside thread Thread[Thread-4,5,main] that has not called Looper.prepare()
。所以我添加了对 Looper 的调用,但这给了我
Error starting Python server: Method addObserver must be called on the main thread
,即使运行 Quart 应用程序的调用是在启动 Python 解释器的线程中。

科特林:

package com.example.chatterbot

import android.annotation.SuppressLint
import android.net.http.SslError
import android.os.Bundle
import android.os.Looper
import android.util.Log
import android.webkit.SslErrorHandler
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.chaquo.python.Python
import com.chaquo.python.android.AndroidPlatform

class MainActivity : AppCompatActivity() {

    private val tag: String = "MainActivity" // Define a tag for your logs
    private var serverPort: Int? = null
    private lateinit var webView: WebView
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Run the Python server in a background thread
        Thread {
            Looper.prepare()
            Log.i(tag, "Starting server")
            Log.i(tag, "IS STARTED")
            Log.i(tag, Python.isStarted().toString())
            if (! Python.isStarted()) {
                Python.start(AndroidPlatform(this))
            }
            try {
                val py = Python.getInstance()
                py.getModule("app").callAttr("run")
            } catch (e: Exception) {
                Log.e(tag, "Error starting Python server: ${e.message}")
            }
            Looper.loop()
        }.start()

        // Set webview
        Log.i(tag, "Starting webview")
        webView = findViewById(R.id.webview)
        webView.webViewClient = object : WebViewClient() {
            override fun onReceivedSslError(
                view: WebView?,
                handler: SslErrorHandler?,
                error: SslError?
            ) {
                // Ignore SSL certificate errors (not recommended for production)
                handler?.proceed()
            }
        }
        webView.settings.javaScriptEnabled = true
        webView.loadUrl("file:///android_asset/iframe/iframe.html")
        swipeRefreshLayout = findViewById(R.id.swipe_refresh_layout)
        swipeRefreshLayout.setOnRefreshListener {
            webView.reload() // Reload the current page
            swipeRefreshLayout.isRefreshing = false // Stop the refreshing animation
        }
    }

    fun closeLoader() {
        Log.i(tag, "Close loader")
        webView.evaluateJavascript("closeLoader();", null)
    }

}

Python:

from hypercorn.asyncio import serve
from hypercorn.config import Config
from quart import Quart, render_template
from com.example.chatterbot import MainActivity

activity = MainActivity() # <-- **The problem comes when i add this**

app = Quart(__name__)

config = Config()
config.bind = [f"0.0.0.0:8000"]
config.debug = True

@app.route('/')
async def index():
    return await render_template('index.html')

@app.after_serving
async def after_startup():
    # This code will run after the server is fully loaded and ready to receive requests
    print("Server ready")
    activity.closeLoader()

def run():
    app.run(host="0.0.0.0", port=8000, debug=True)
python android multithreading kotlin chaquopy
1个回答
0
投票

正如评论中所说,解决方案是这里

© www.soinside.com 2019 - 2024. All rights reserved.