这是我正在努力做的最小版本。这是我的main.py
文件:
class MainScreen(Screen):
def __init__(self):
super(MainScreen, self).__init__()
self.url_input = TextInput()
self.start = Button(text='Download')
self.start.bind(on_release=partial(self.on_start_press))
self.add_widget(self.url_input)
self.add_widget(self.start)
def on_start_press(self, *args):
DownloadTask(self.url_input.text)
...
这是我的task.py文件,其中包含DownloadTask
。
class DownloadTask(object):
def __init__(self, url):
self.url = url
self._get_headers()
def _get_headers(self):
UrlRequest(url=self.url, on_success=self._on_headers_fetched, method='HEAD')
def _on_headers_fetched(self, req, resp):
self.content_length = int(req.resp_headers.get('Content-Length'))
但是从不调用on_success回调。在urlrequest.py
的第439行:
if self.on_success:
func = self.on_success()
if func:
func(self, data)
func
为None
,因此不会调用回调。在尝试访问weakmethod.py
时,ReferenceError: weakly-referenced object no longer exists
中的第47行也会引发self.proxy
。
try:
if self.proxy:
return getattr(self.proxy, self.method_name)
except ReferenceError:
pass
return self.method
这是什么问题?我的DownloadTask()
对象是垃圾收集了吗?
Environemnt:Python 3.5.3,Kivy 1.10.0,mac os
答案 0 :(得分:2)
修改:source显示后,在我看来DownloadTask
对象是垃圾收集的,因此Thread
运行UrlRequest
1}} called一个WeakProxy
用于不存在的对象的方法 - 因此崩溃。
是否是垃圾收集我不确定,但请求会创建一个守护进程Thread
,因此你不应该太在意(随意找出)。关于它有一个comment,所以可能还没有收集呢。
UrlRequest
然而强烈依赖于Kivy而且可见here。它使用Kivy Clock
。这意味着除非运行Kivy应用程序,否则请求将不会继续进行,即它应该停止on this line。只需尝试将任意print('something')
添加到UrlRequest._dispatch_result()
,您就会看到它被完全忽略,因为Kivy Clock
没有勾选(因此函数未被调用)。
但是在这个例子中,运行实际的Kivy应用程序时,我没有看到它的问题。
from kivy.app import runTouchApp
from kivy.uix.widget import Widget
from kivy.network.urlrequest import UrlRequest
class My(Widget):
def __init__(self, **kwargs):
super(My, self).__init__(**kwargs)
UrlRequest(
url='http://lipsum.com/',
on_error=lambda *args: print('error:', args),
on_failure=lambda *args: print('fail:', args),
on_redirect=lambda *args: print('redir:', args),
on_success=lambda *args: print('success:', args)
)
runTouchApp(My())