Kivy android 应用程序 - 在 __javainterfaces__ 中使用自定义接口时,pyjnius.PythonJavaClass 无法与 buildozer 一起使用

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

这是一个更大的应用程序的简化版本,需要一个java类有一个python实现,以便必须是java的回调对象可以调用python方法,你可以在这里找到该项目:https://github.com /lookbehindyounow/remote_mouse

我制作这个版本是为了尝试并隔离问题,基本上它所做的就是启动一个 kivy 应用程序并将“hi”打印到控制台。

main.py:

from jnius import autoclass, PythonJavaClass, java_method
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label

class Print(PythonJavaClass):
    __javainterfaces__=["com/example/IPrint"]
    @java_method("(Ljava/lang/String;)V")
    def jprint(self,message):
        print(message)

Holder=autoclass("com.example.Holder")
JavaPrint=autoclass("com.example.Print")

class Test(App):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.printer=Print()
        # self.printer=JavaPrint()
        self.holder=Holder(self.printer)
        self.holder.jprint("hi")
    
    def build(self):
        return MainWidget()

class MainWidget(Widget):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.add_widget(Label(text="kivy working"))

Test().run()

打印.java:

package com.example;

import com.example.IPrint;

public class Print implements IPrint{
    public void jprint(String message){
        System.out.println(message);
    }
}

IPrint.java:

package com.example;

public interface IPrint{
    public void jprint(String message);
}

Holder.java:

package com.example;
import com.example.IPrint;

public class Holder{
    public IPrint printer;
    public Holder(IPrint printer){
        this.printer=printer;
    }
    public void jprint(String message){
        this.printer.jprint(message);
    }
}

这里是buildozer.spec的一些部分,用省略号分隔,其余都是默认设置:

# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas,java
...
# (list) Application requirements
# comma separated e.g. requirements = sqlite3,kivy
requirements = python3,kivy,kivymd,pyjnius
...
# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
android.add_src = java

错误:

<originating from main.py: self.printer=Print()>
jnius.jnius.JavaException: JVM exception occurred: interface com.example.IPrint is not visible from class loader java.lang.IllegalArgumentException

如果在 main.py 中我取消注释 self.printer=JavaPrint() 它工作正常,所以我知道问题出在 Print(PythonJavaClass) 上,但我不知道是什么。如果我拼写错误 __javainterfaces__=["com/example/IPrint"] 它会给出不同的错误:

<originating from main.py: self.printer=Print()>
jnius.jnius.JavaException: JVM exception occurred: Didn't find class "com.example.IPrintaaa" on path: <long path> java.lang.ClassNotFoundException

所以我知道 __javainterfaces__=["com/example/IPrint"] 正在选择正确的东西。更重要的是,它在我的 MacBook 上运行良好,这是使用 buildozer 构建的应用程序,但在我的 Android 手机上无法运行。

我尝试将java类编译成jar文件并相应地更新spec文件,没有区别。仅用于 IPrint 的第二个 jar 文件会抛出错误,指出重复的资源。我无法使用 pyjnius autoclass 或 JavaClass 成功加载接口,它在实例化 Print(PythonJavaClass) 时给出了不同的错误,但在 macbook 上也会发生这种情况。

希望这一切都有道理,干杯。

android kivy classloader buildozer pyjnius
1个回答
0
投票
class Print(PythonJavaClass):
    __javainterfaces__=["com/example/IPrint"]
    __javacontext__="app"
    @java_method("(Ljava/lang/String;)V")
    def jprint(self,message):
        print(message)
© www.soinside.com 2019 - 2024. All rights reserved.