Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit124df71

Browse files
OSUpdate app: use update_ui_threadsafe_if_foreground
Now it no longer crashes if the user moves away while the OSUpdate is ongoing.
1 parenta1ac5a6 commit124df71

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

‎internal_filesystem/builtin/apps/com.micropythonos.osupdate/assets/osupdate.py‎

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
classOSUpdate(Activity):
1212

13-
keep_running=True
1413
download_update_url=None
1514

1615
# Widgets:
@@ -58,9 +57,6 @@ def onStart(self, screen):
5857
print("Showing update info...")
5958
self.show_update_info()
6059

61-
defonStop(self,screen):
62-
self.keep_running=False# this is checked by the update_with_lvgl thread
63-
6460
defshow_update_info(self):
6561
self.status_label.set_text("Checking for OS updates...")
6662
hwid=mpos.info.get_hardware_id()
@@ -140,8 +136,8 @@ def force_update_clicked(self):
140136

141137
defprogress_callback(self,percent):
142138
print(f"OTA Update:{percent:.1f}%")
143-
lv.async_call(lambdal:self.progress_label.set_text(f"OTA Update:{percent:.2f}%"),None)
144-
lv.async_call(lambdal:self.progress_bar.set_value(int(percent),True),None)
139+
self.update_ui_threadsafe_if_foreground(self.progress_bar.set_value,int(percent),True)
140+
self.update_ui_threadsafe_if_foreground(self.progress_label.set_text,f"OTA Update:{percent:.2f}%")
145141
time.sleep_ms(100)
146142

147143
# Custom OTA update with LVGL progress
@@ -168,7 +164,7 @@ def update_with_lvgl(self, url):
168164
i=0
169165
total_size=round_up_to_multiple(total_size,chunk_size)
170166
print(f"Starting OTA update of size:{total_size}")
171-
whileself.keep_running:# stop if the user navigates away
167+
whileself.has_foreground():# stop if the user navigates away
172168
time.sleep_ms(100)# don't hog the CPU
173169
chunk=response.raw.read(chunk_size)
174170
ifnotchunk:
@@ -187,7 +183,7 @@ def update_with_lvgl(self, url):
187183
response.close()
188184
try:
189185
ifbytes_written>=total_size:
190-
lv.async_call(lambdal:self.status_label.set_text("Update finished! Please restart."),None)
186+
lv.update_ui_threadsafe_if_foreground(self.status_label.set_text,"Update finished! Please restart.")
191187
ifnotsimulate:# if the update was completely installed
192188
next_partition.set_boot()
193189
importmachine
@@ -196,12 +192,11 @@ def update_with_lvgl(self, url):
196192
else:
197193
print("This is an OSUpdate simulation, not attempting to restart the device.")
198194
else:
199-
lv.async_call(lambdal:self.status_label.set_text(f"Wrote{bytes_written} <{total_size} so not enough!"),None)
200-
self.install_button.remove_state(lv.STATE.DISABLED)# allow retry
195+
self.update_ui_threadsafe_if_foreground(self.status_label.set_text,f"Wrote{bytes_written} <{total_size} so not enough!")
196+
self.update_ui_threadsafe_if_foreground(self.install_button.remove_state,lv.STATE.DISABLED)# allow retry
201197
exceptExceptionase:
202-
ifself.keep_running:
203-
lv.async_call(lambdal:self.status_label.set_text(f"Update error:{e}"),None)
204-
self.install_button.remove_state(lv.STATE.DISABLED)# allow retry
198+
self.update_ui_threadsafe_if_foreground(self.status_label.set_text,f"Update error:{e}")
199+
self.update_ui_threadsafe_if_foreground(self.install_button.remove_state,lv.STATE.DISABLED)
205200

206201
# Non-class functions:
207202

‎internal_filesystem/lib/mpos/app/activity.py‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
importlvglaslv
12
importmpos.ui
23

34
classActivity:
@@ -6,15 +7,16 @@ def __init__(self):
67
self.intent=None# Store the intent that launched this activity
78
self.result=None
89
self._result_callback=None
10+
self._has_foreground=None
911

1012
defonCreate(self):
1113
pass
1214
defonStart(self,screen):
1315
pass
1416
defonResume(self,screen):# app gets foreground
15-
pass
17+
self._has_foreground=True
1618
defonPause(self,screen):# app goes to background
17-
pass
19+
self._has_foreground=False
1820
defonStop(self,screen):
1921
pass
2022
defonDestroy(self,screen):
@@ -55,3 +57,23 @@ def finish(self):
5557
self._result_callback=None# Clean up
5658
exceptAttributeErrorase:
5759
self.initError(e)
60+
61+
# Apps may want to check this to cancel heavy operations if the user moves away
62+
defhas_foreground(self):
63+
returnself._has_foreground
64+
65+
# Execute a function if the Activity is in the foreground
66+
defif_foreground(self,func,*args,**kwargs):
67+
ifself._has_foreground:
68+
returnfunc(*args,**kwargs)
69+
else:
70+
print(f"[if_foreground] Skipped{func} because _has_foreground=False")
71+
returnNone
72+
73+
# Update the UI in a threadsafe way if the Activity is in the foreground
74+
defupdate_ui_threadsafe_if_foreground(self,func,*args,**kwargs):
75+
# lv.async_call() is needed to update the UI from another thread than the main one (as LVGL is not thread safe)
76+
lv.async_call(
77+
lambda_:self.if_foreground(func,*args,**kwargs),
78+
None
79+
)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp