Kivy Apk Buildozer:ReferenceError:弱引用对象不再存在

Posted

技术标签:

【中文标题】Kivy Apk Buildozer:ReferenceError:弱引用对象不再存在【英文标题】:Kivy Apk Buildozer : ReferenceError: weakly-referenced object no longer exists 【发布时间】:2020-07-19 22:29:30 【问题描述】:

谁能告诉我为什么我的应用程序崩溃了。很奇怪,当我第一次运行我的应用程序时它没有崩溃。但是下次我运行它时它会崩溃。我得到这样的东西。 我正在使用 KIVYMD、KIVY、SOCKET、KIVY MAPVIEW、SQLITE3。下面是我通过 buildozer logcat 得到的错误。

04-07 21:49:46.650  4622  4659 I python  : [WARNING] [Base        ] Unknown <android> provider
04-07 21:49:46.656  4622  4659 I python  : [INFO   ] [Base        ] Start application main loop
04-07 21:49:48.162  4622  4659 I python  : [INFO   ] [Base        ] Leaving application in progress...
04-07 21:49:48.163  4622  4659 I python  :  Traceback (most recent call last):
04-07 21:49:48.163  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/app/main.py", line 504, in <module>
04-07 21:49:48.164  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/app.py", line 855, in run
04-07 21:49:48.164  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/base.py", line 504, in runTouchApp
04-07 21:49:48.165  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/core/window/window_sdl2.py", line 747, in mainloop
04-07 21:49:48.165  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/core/window/window_sdl2.py", line 479, in _mainloop
04-07 21:49:48.166  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/base.py", line 339, in idle
04-07 21:49:48.166  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/clock.py", line 591, in tick
04-07 21:49:48.167  4622  4659 I python  :    File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
04-07 21:49:48.167  4622  4659 I python  :    File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
04-07 21:49:48.168  4622  4659 I python  :    File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
04-07 21:49:48.168  4622  4659 I python  :    File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
04-07 21:49:48.169  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/uix/label.py", line 417, in texture_update
04-07 21:49:48.169  4622  4659 I python  :    File "kivy/properties.pyx", line 497, in kivy.properties.Property.__set__
04-07 21:49:48.170  4622  4659 I python  :    File "kivy/properties.pyx", line 839, in kivy.properties.ListProperty.set
04-07 21:49:48.170  4622  4659 I python  :    File "kivy/properties.pyx", line 544, in kivy.properties.Property.set
04-07 21:49:48.171  4622  4659 I python  :    File "kivy/properties.pyx", line 599, in kivy.properties.Property.dispatch
04-07 21:49:48.176  4622  4659 I python  :    File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
04-07 21:49:48.177  4622  4659 I python  :    File "kivy/_event.pyx", line 1096, in kivy._event.EventObservers._dispatch
04-07 21:49:48.177  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/lang/builder.py", line 76, in call_fn
04-07 21:49:48.178  4622  4659 I python  :    File "kivy/weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
04-07 21:49:48.178  4622  4659 I python  :    File "kivy/properties.pyx", line 497, in kivy.properties.Property.__set__
04-07 21:49:48.178  4622  4659 I python  :    File "kivy/properties.pyx", line 544, in kivy.properties.Property.set
04-07 21:49:48.179  4622  4659 I python  :    File "kivy/properties.pyx", line 599, in kivy.properties.Property.dispatch
04-07 21:49:48.179  4622  4659 I python  :    File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
04-07 21:49:48.180  4622  4659 I python  :    File "kivy/_event.pyx", line 1096, in kivy._event.EventObservers._dispatch
04-07 21:49:48.180  4622  4659 I python  :    File "/home/tenzin/EcoMap/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/myapp/kivy/lang/builder.py", line 73, in call_fn
04-07 21:49:48.181  4622  4659 I python  :    File "<string>", line 54, in <module>
04-07 21:49:48.181  4622  4659 I python  :    File "kivy/weakproxy.pyx", line 32, in kivy.weakproxy.WeakProxy.__getattr__
04-07 21:49:48.182  4622  4659 I python  :    File "kivy/weakproxy.pyx", line 28, in kivy.weakproxy.WeakProxy.__ref__
04-07 21:49:48.182  4622  4659 I python  :  ReferenceError: weakly-referenced object no longer exists
04-07 21:49:48.182  4622  4659 I python  : Python for android ended.

这是我的主要代码:

from kivymd.app import MDApp
from kivymd.uix.taptargetview import MDTapTargetView
from kivy.properties import ObjectProperty
from kivy.garden.mapview import MapView ,MapMarker,MapMarkerPopup
from kivy.uix.screenmanager import Screen,ScreenManager,SlideTransition
from kivymd.uix.snackbar import Snackbar
from kivy.uix.floatlayout import FloatLayout
from kivymd.uix.tab import MDTabsBase
import sqlite3
import socket
from kivy.clock import Clock
from kivymd.uix.dialog import MDDialog,MDInputDialog
from kivymd.uix.list import IRightBodyTouch, OneLineAvatarIconListItem
from kivy.properties import StringProperty
from kivymd.uix.selectioncontrol import MDSwitch
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle
from kivy.graphics.texture import Texture
from kivymd.uix.list import MDList
from gpsblinker import GpsBlinker

publ_ipv4 = "my server ip(for eg)"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((publ_ipv4,12345))
from gpshelper import GpsHelper
rtr_count = 0
def send_mes(mes):
    s.send(str(mes).encode("utf-8"))
#Connect to the local account database
account_db = sqlite3.connect("account.db")

ac_db_cur = account_db.cursor()

ac_db_cur.execute("SELECT * FROM accounts")
def remove():
    ac_db_cur.execute("DELETE FROM accounts")
    ac_db_cur.execute("DELETE FROM avatar")
    account_db.commit()
tutorial = False
usr_ac_cred = ac_db_cur.fetchall()
print(usr_ac_cred)
logged_in = None

if len(usr_ac_cred) == 0:
    logged_in = False
elif len(usr_ac_cred) != 0:

    logged_in = True
    print(logged_in)
class ScreenOne(Screen):
    pass
class ScreenTwo(Screen):
    pass
class ScreenThree(Screen):
    pass


class LocationPopupMenu(MDDialog):
    def build(self):
        self.title = "Trashcan"
        self.text = "If there is no trashcan here. You can remove this."
        self.text_button_ok = "Remove"
        self.text_button_cancel = "Cancel"

    def __init__(self, lat,lon):
        self.build()
        super().__init__()

        self.events_callback = self.remove(lon,lat)


    def remove(self,lon,lat):
        send_mes(["rm",[lon,lat]])



class TrashMarker(MapMarkerPopup):


    def on_release(self):
        # Open up the LocationPopupMenu
        menu = LocationPopupMenu(self.lat,self.lon)
        menu.size_hint = [.3, .3]
        menu.open()

class SearchPopupMenu(MDInputDialog):
    title = "Search by Address"
    text_button_ok = "Search"
    def __init__(self):
        super().__init__()
        self.size_hint = [.8,.3]
        self.opacity = 1
        self.events_callback = self.callback
    def callback(self,*args):
        address = self.text_field.text
        self.geocode_get_lat_lon(address)
    def geocode_get_lat_lon(self,address):
        print("hello")



class Main(MapView):
    getting_markers_timer = None


    def start_getting_markers_in_fov(self):
        self.map_source = "osm"
        #after one second get markers in fov\
        try :

            self.getting_markers_timer.cancel()
        except:
            pass
        self.getting_markers_timer = Clock.schedule_once(self.get_markers_in_fov,1)

    def get_markers_in_fov(self,*args):


        unp_bound = self.get_bbox()

        lo = unp_bound[1]
        lo_p = unp_bound[3]
        la = unp_bound[0]
        la_p = unp_bound[2]

        ac_db_cur.execute("SELECT DISTINCT * FROM mpmr WHERE lon > %s AND lon < %s AND lat > %s AND lat < %s" % (
                    lo, lo_p, la, la_p))
        mkr_data = ac_db_cur.fetchall()
        print(mkr_data)

        for set in mkr_data:
            self.add_marker(TrashMarker(lat = set[1],lon = set[0]))
        print("done")
class MyWidget(Widget):
    def __init__(self, **args):
        super(MyWidget, self).__init__(**args)
        self.texture = Texture.create(size=(2, 2), colorfmt='rgba')

        p1_color = [255, 96, 27, 255]
        p2_color = [255, 0, 133, 255]
        p3_color = [206, 255, 0, 255]
        p4_color = [232, 202, 0, 255]
        p1_color = [0, 171, 146, 255]
        p2_color = [0, 174, 109, 255]
        p3_color = [0, 138, 175, 255]
        p4_color = [15, 154, 174, 255]

        p = p1_color + p2_color + p3_color + p4_color
        buf = bytes(p)
        self.texture.blit_buffer(buf, colorfmt='rgba', bufferfmt='ubyte')
        with self.canvas:
            self.rect = Rectangle(pos=self.pos, size=self.size, texture=self.texture)

        self.bind(size=self.update_rect)
        self.bind(pos=self.update_rect)

    def update_rect(self, *args):
        self.rect.size = self.size
        self.rect.pos = self.pos

#load map
settings_db = sqlite3.connect("Settings.db")
cur = settings_db.cursor()

cur.execute("select * from settings")
data_un= cur.fetchall()
print(data_un)






class DrawerList(ThemableBehavior, MDList):
    def set_color_item(self, instance_item):
        '''Called when tap on a menu item.'''

        # Set the color of the icon and text for the menu item.
        for item in self.children:
            if item.text_color == self.theme_cls.primary_color:
                item.text_color = self.theme_cls.text_color
                break
        instance_item.text_color = self.theme_cls.primary_color

class Settings_screen_list(OneLineAvatarIconListItem):
    icon = StringProperty("android")
class Right_switch(IRightBodyTouch,MDSwitch):
    pass


class Manager(ScreenManager):
    Home = ObjectProperty(None)
    Settings = ObjectProperty(None)

class Tab(FloatLayout, MDTabsBase):
    '''Class implementing content for a tab.'''


class MainApp(MDApp):
    data = 
        "help-circle-outline" : "Help",
        "mapbox" : "Add Trashcan",
        "settings" : "settings"
    
    myscreen = ObjectProperty()
    search_menu= None



    def on_start(self):
        self.root.ids.parent_manager.transition = SlideTransition()
        self.root.ids.manager.transition =  SlideTransition()
        self.root.ids.manager.transition.direction = "left"
        self.root.ids.manager.transition.direction = "left"


        try:
            self.root.ids.avatar_usr.source = ac_db_cur.execute("SELECT * FROM avatar").fetchall()[0][0]
            self.root.ids.avatar_usr_2.source = ac_db_cur.execute("SELECT * FROM avatar").fetchall()[0][0]
            self.root.ids.uad_username.text = usr_ac_cred[0][1].title()
            self.root.ids.uad_email.text = usr_ac_cred[0][0]
            self.root.ids.nav_username.text = usr_ac_cred[0][1].title()
            self.root.ids.nav_email.text = usr_ac_cred[0][0]
            #initialize gps

        except:
            pass

    def build(self):

        #Accessing settings database
        cur.execute("SELECT mode from settings where attribute='darkmode' ")
        GpsHelper().run()
        lat = self.root.ids.blinker.lat
        lon = self.root.ids.blinker.lon
        gps_stat = [[lon,lat],"app_gps"]
        send_mes(gps_stat)
        response = s.recvfrom(100000)
        response = eval(response[0].decode("utf-8"))
        print(response)
        if response[0] == "db_register":
            ac_db_cur.execute("DELETE FROM mpmr")
            for or_pair in response[1]:
                sql_scr = "INSERT INTO mpmr VALUES("+str(or_pair[0])+","+str(or_pair[1])+")"

                ac_db_cur.execute(sql_scr)
            account_db.commit()



        #App theme and UI color schemes
        darkmode_opt_list = cur.fetchall()
        darkmode_opt = darkmode_opt_list[0][0]
        self.theme_cls.primary_palette = "Cyan"
        self.theme_cls.primary_hue = "800"
        self.theme_cls.accent_palette  = "Gray"
        self.theme_cls.accent_hue = "50"
        self.search_menu = SearchPopupMenu()

        self.tap_target_view = MDTapTargetView(
            widget=self.root.ids.button,
            title_text="Click here to locate you.",
            description_text="Make sure we are right over you",
            widget_position="left_bottom",
        )
        if darkmode_opt == "on":
            print("dark mode on")
            self.theme_cls.theme_style = "Dark"
            self.root.ids.darkmode_switch.active= True
        else:
            print("light mode on")
            self.theme_cls.theme_style = "Light"
            self.root.ids.darkmode_switch.active = False


        if logged_in == True:
            self.root.ids.manager.current = "Home"


            def repos(button):
                self.root.ids.ecomap.center_on(self.root.ids.blinker.lat,self.root.ids.blinker.lon)
                self.root.ids.ecomap.zoom = 18

            self.tap_target_view.bind(on_close=repos)

            def drop_marker_db(button):
                pass
                # temp_marker = MapMarker(lat=val[0], lon=val[1])
                # screen.ids.ecomap.add_marker(temp_marker)

            try:
                self.start_anim.cancel()
            except:
                pass
            self.start_anim = Clock.schedule_once(self.start_tp_anim, 3.5)



        elif logged_in == False:
            self.root.ids.parent_manager.current = "account_setup"


    def start_app(self):

        self.root.ids.parent_manager.current = "parent"
        self.root.ids.manager.current = "Home"
        usr_ac_cred = ac_db_cur.execute("SELECT * FROM accounts").fetchall()
        self.root.ids.uad_username.text = usr_ac_cred[0][1]
        self.root.ids.uad_email.text = usr_ac_cred[0][0]
        self.root.ids.nav_username.text = usr_ac_cred[0][1]
        self.root.ids.nav_email.text = usr_ac_cred[0][0]
        print(self.root.ids.blinker.lat)
        print(self.root.ids.blinker.lon)

    def start_tp_anim(self,*args):
        self.tap_target_start()
    def init_dark_mode(self,select,value):
        if value:
            self.theme_cls.theme_style = "Dark"
            cur.execute("UPDATE settings SET mode='on' WHERE attribute = 'darkmode'")
            settings_db.commit()
        else:
            self.theme_cls.theme_style = "Light"
            cur.execute("UPDATE settings SET mode='off' WHERE attribute = 'darkmode'")
            settings_db.commit()
    def tap_target_start(self):
        if self.tap_target_view.state == "close":
            self.tap_target_view.start()
        else:
            self.tap_target_view.stop()
    def callback(self,instance):
        if instance.icon == "settings":
            self.root.ids.manager.transition.direction = "left"
            self.root.ids.manager.current = "Settings"
        elif instance.icon == "mapbox":
            self.register_trashcan()
        elif instance.icon == "help-circle-outline":
            self.root.ids.manager.transition.direction = "left"
            self.root.ids.manager.current = "help"

    def open_account(self):
        self.root.ids.parent_manager.current="User_account_details"
        self.root.ids.parent_manager.transition.direction = "left"
        self.root.ids.manager.transition.direction = "left"

    def open_home(self):
        self.root.ids.manager.current="Home"
    def sign_up(self):
        username = self.root.ids.name_field.text
        email = self.root.ids.email_field.text
        password = self.root.ids.password_field.text
        Acc_list = ["acc", username, email, password]
        if username == "" or email == ""or password == "":
            if username == "":
                self.root.ids.name_field.hint_text = "Name field cannot be empty!"
            elif email == "":
                self.root.ids.email_field.hint_text = "Email field cannot be empty!"
            elif password == "":
                self.root.ids.password_field.hint_text = "Password field cannot be empty!"
        else :
            print(Acc_list)
            send_mes(Acc_list)
            response  = s.recvfrom(1024)


            response = str(response[0].decode("utf-8"))
            print(response)
            if response == "ACCOUNT CREATED":
                sql_script = "INSERT INTO accounts VALUES('" + email + "', '" + username + "' , '" + password + "')"
                ac_db_cur.execute(sql_script)
                account_db.commit()
                self.root.ids.parent_manager.current = "profile_picture_opt"
                self.root.ids.uad_username.text = username
                self.root.ids.uad_email.text = email
                self.root.ids.nav_username.text = username
                self.root.ids.nav_email.text = email
                GpsHelper().run()
                tutorial = True
            elif response == "EM_AL_EX":
                self.root.ids.email_field.text = ""
                self.root.ids.email_field.hint_text = "Email Id is already used!"
        #register this account to server database


        #register this account credentials to localhost database

    def go_to_login(self):
        self.root.ids.parent_manager.current = "login_screen"
        self.root.ids.parent_manager.transition.direction = "left"

    def login(self):

        if len(self.root.ids.login_email_field.text) == 0  or len(self.root.ids.login_pw_field.text) == 0:
            self.root.ids.login_email_field.hint_text = "Email field cannot be empty"
            self.root.ids.login_pw_field.hint_text = "Password field cannot be empty"
        else:
            print("hey look over here")
            print(type(self.root.ids.login_email_field.text))
            print(type(self.root.ids.login_pw_field.text))
            cred_cont = [(self.root.ids.login_email_field.text.lower(),"",self.root.ids.login_pw_field.text),"ch_acc_cred"]
            send_mes(cred_cont)
            response = s.recvfrom(1024)
            response = str(response[0].decode("utf-8"))
            if response == "error_lia":
                pass
            else:
                response = eval(response)
                if response[0]=="verified":
                    sql_scr1 = "DELETE FROM accounts"
                    sql_scr2 = "INSERT INTO accounts VALUES('"+self.root.ids.login_email_field.text+"', '"+response[1]+"' , '"+self.root.ids.login_pw_field.text+"')"
                    ac_db_cur.execute(sql_scr1)
                    ac_db_cur.execute(sql_scr2)
                    account_db.commit()
                    global logged_in
                    logged_in = True
                    self.root.ids.parent_manager.current = "profile_picture_opt"
                    self.root.ids.parent_manager.transition.direction = "left"
                    GpsHelper().run()
                    tutorial = True


    def confirm_av(self):
        usr_av = None
        selected = None

        for avatar in [self.root.ids.m1,self.root.ids.m2,self.root.ids.m3,self.root.ids.m4,self.root.ids.m5,self.root.ids.m6,self.root.ids.m7,self.root.ids.w1,self.root.ids.w2,self.root.ids.w3,self.root.ids.w4,self.root.ids.w5,self.root.ids.w6,self.root.ids.w7]:

            if avatar.size == [250,250]:

                selected = True
                break
        if selected == True:
            ac_db_cur.execute("DELETE FROM avatar")
            ac_db_cur.execute("INSERT INTO avatar VALUES('"+avatar.icon+"')")
            account_db.commit()
            self.start_app()
            av = ac_db_cur.execute("SELECT * FROM avatar").fetchall()[0][0]

            self.root.ids.avatar_usr.source = av
            self.root.ids.avatar_usr_2.source = av
        else :
            pass
    def confirm_ava(self):
        usr_av = None
        selected = None

        for avatar in [self.root.ids.m1a,self.root.ids.m2a,self.root.ids.m3a,self.root.ids.m4a,self.root.ids.m5a,self.root.ids.m6a,self.root.ids.m7a,self.root.ids.w1a,self.root.ids.w2a,self.root.ids.w3a,self.root.ids.w4a,self.root.ids.w5a,self.root.ids.w6a,self.root.ids.w7a]:

            if avatar.size == [250,250]:

                selected = True
                break
        if selected == True:
            ac_db_cur.execute("DELETE FROM avatar")
            ac_db_cur.execute("INSERT INTO avatar VALUES('"+avatar.icon+"')")
            account_db.commit()

            av = ac_db_cur.execute("SELECT * FROM avatar").fetchall()[0][0]

            self.root.ids.avatar_usr.source = av
            self.root.ids.avatar_usr_2.source = av
        else :
            pass
    def register_trashcan(self):
        lat = self.root.ids.blinker.lat
        lon = self.root.ids.blinker.lon
        list = ["tr_reg",[lat,lon]]
        send_mes(list)
        self.snackbar = Snackbar(text="Trashcan added.Will be shown soon!")
        self.snackbar.show()

    def dev(self):
        self.snackbar = Snackbar(text="Developer : Tenzin Dayoe")
        self.snackbar.show()


    def sign_out(self):
        ac_db_cur.execute("DELETE FROM accounts ")
        ac_db_cur.execute("DELETE FROM avatar")
        account_db.commit()

        self.root.ids.parent_manager.current = "account_setup"
        self.root.ids.email_field.text = ""
        self.root.ids.name_field.text = ""
        self.root.ids.password_field.text = ""
    def send_fb(self):

        fb_email = self.root.ids.feedback_email.text
        fb_data = self.root.ids.feedback_data.text
        if len(fb_email) != 0 and len(fb_data) != 0:
            fb_container = [[fb_email, fb_data],"feedback"]
            send_mes(fb_container)
            self.snackbar = Snackbar(text="Sent. Thank you!")
            self.snackbar.show()
            self.root.ids.feedback_email.text = ""
            self.root.ids.feedback_data.text = ""
        else:
            if len(fb_email) == 0:
                self.root.ids.feedback_email.hint_text = "Email id required!"
            if len(fb_data) == 0:
                self.root.ids.feedback_data.hint_text = "Type Feedback or bugs you've found in the App! "
MainApp().run()

【问题讨论】:

您的示例太复杂,无法查看,请提供一个最小的示例。要产生这样的东西,请删除部分代码,直到错误不再出现,然后添加回最后的内容并继续删除更多内容。作为奖励,这很可能会帮助您找到导致问题的代码区域。 【参考方案1】:

我遇到了同样的问题。在我的情况下,我通过用 3.7.5 而不是 3.8.1 替换我的 hostpython3 来解决这个问题。在您的 buildozer.spec 要求中,您需要输入 hostpython3==3.7.5, python3==3.7.5 。之后删除您的文件夹 .buildozer/android/platform/build-armeabi 并重试构建您的应用程序。

【讨论】:

以上是关于Kivy Apk Buildozer:ReferenceError:弱引用对象不再存在的主要内容,如果未能解决你的问题,请参考以下文章

Kivy App 使用 Buildozer 构建。 APK 崩溃

使用 buildozer 创建 kivy apk 错误:“Aidl 无法执行”

由 buildozer 构建的 Kivy apk 在显示预启动屏幕后很快崩溃

buildozer(kivy,python) 无法将生成的 apk 复制到 docker 虚拟机上的主目录

Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m "kivy" d

Kivy Apk Buildozer:ReferenceError:弱引用对象不再存在