如何处理想要更新应用程序UI的后台线程
介绍
虽然可以为iOS / Android系统(或桌面)轻松开发没有线程操作的简单应用程序,但是当线程涉及时,事情会变得模糊。那我们该怎么处理呢?
背景
我需要处理的大多数应用程序必须处理多个线程,多年来,我学会了一些简单的技术(当你通过错误学习时很简单)并且想要分享其中一些用于App开发。
假设我通过套接字从服务器收到一些即时通知消息,我需要在UI页面中显示这些消息。
由于通知是通过套接字传递的,因此很可能会在后台线程中发生。通常,当我们通过套接字接收数据时,将创建多个线程。
大多数初学者都遇到了更新GUI并将数据保存在他们收到的通知中的问题,这会使应用程序处于非常不稳定的状态。
因此,在解决问题时,请记住以下三个关键事项:
- 在后台读取/获取/接收数据以确保应用程序不会挂起/等待/冻结传入数据。无论如何,套接字通知通常都来自后台线程。
- 以短突发形式在前台线程中写入/存储数据。通常将请求发布到应用程序的UI /主线程以运行存储操作会自动处理线程同步。如果操作昂贵,请使用排队服务。
- 反映主/ UI线程中GUI的更改。
通常,如果我们不必存储太多信息或更新太多模型,我们可以简单地向系统发布请求,以便在我们在后台线程中接收数据时在main / UI线程中运行下一组操作。
在我们的例子中,如果我们在onMessage事件中接收服务器通知消息,在事件处理程序内,我们可以使用代码,例如(取决于Android / iOS):
runOnUIThread/dispatch_get_main()
更新Model / DB以及UI。
伪代码示例:
void onNewMessage(message){ runOnUIThread->{ // this usually takes care of the thread syncronization db.insertNewMessage(message); updateAllViews(); } }
现在,如果您觉得db / model操作变得昂贵,可以在后台实现Queue服务,以便在DB / models中频繁插入/更新传入的消息。需要在前台实现从队列获取消息以相应地更新GUI。为简单起见,您可以使用队列服务中的事件通知(以及相关信息),请求主线程更新GUI。
在这种情况下,伪代码示例将如下所示:
void onNewMessage(message){ QService.insert(message); } QService.onFinishProcessingMessage(message){ // the UI page/element might register as an observer into the event service EventService.notifyObservers("event_message_processed", message); } uiPage.on("event_message_processed", function(message){ // most likely the event notification would come in a background thread, // so invoke running in main thread for GUI operations/update runOnUIThread->{ updateUI(); } });
快乐的编码!