这是一个更大的应用程序的简化版本,需要一个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 上也会发生这种情况。
希望这一切都有道理,干杯。
class Print(PythonJavaClass):
__javainterfaces__=["com/example/IPrint"]
__javacontext__="app"
@java_method("(Ljava/lang/String;)V")
def jprint(self,message):
print(message)