“背景” 掌上操作系统中的任务
我正在尝试创建一个 Palm OS 应用程序来每 X 分钟或几小时检查一次网站,并在有数据可用时提供通知。 我知道这种事情可以在新的 Palm 上完成 - 例如,当应用程序不在顶部时,我的 Centro 可以下载电子邮件或网站 - 但我不知道该怎么做。 有人能指出我正确的方向吗?
I'm trying to create a Palm OS app to check a web site every X minutes or hours, and provide a notification when a piece of data is available. I know that this kind of thing can be done on the new Palm's - for example, my Centro can have email or web sites download when the application isn't on top - but I don't know how to do it. Can anyone point me in the right direction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是可能做到的,但非常困难。 您必须执行几个步骤。
首先,这仅适用于 Palm OS 5,并且在某些早期的 Palm OS 5 设备上效果不佳。 最新的设备更好,但并不完美。
接下来,您需要使用 AlmSetAlarm 为您的应用程序创建警报。 这就是完成“每 X 分钟或小时”部分的方法。
当警报触发时,您的应用程序将获得 sysAppLaunchCmdAlarmTriggered 启动代码,即使它尚未运行。 如果您只想做一些简单快速的事情,您可以响应启动代码来完成,然后就完成了。
在闹钟启动代码中完成您的操作后,请务必设置下一个闹钟,以便继续被呼叫。
重要提示:响应此启动代码时无法访问全局变量! 根据编译器中的设置,您可能也无法访问某些 C++ 功能,例如虚拟函数(内部使用全局变量)。 您可以在 Codewarrior 中设置一个设置,这将有助于解决此问题,但我对此不太熟悉。 您应该构建您的代码,以便它不需要全局变量; 例如,您可以使用 FtrSet 和 FtrGet 来存储您可能需要的全局数据位。 最后,您将只能访问 68000 个机器代码的单个 64KB 代码段。 如果没有设置全局变量,段间跳转将无法正常工作。
您可以通过将大部分代码移至 PNOlet 来绕过许多这些限制,但这是一个完全不同且更复杂的主题。
如果您想做一些可能需要一段时间的更复杂的事情(例如加载网页或下载电子邮件),强烈建议不要在警报启动代码期间执行此操作。 您可以在 sysAppLaunchCmdDisplayAlarm 启动代码中执行某些操作,并向用户显示一个表单,允许他们取消。 但这肯定很快就会变得烦人。
对于用户体验来说更好(但更复杂)的是成为后台应用程序。 这有点黑魔法,并没有得到很好的支持,但它是可能的。 成为后台应用程序基本上分为三个步骤:
使用 DmDatabaseProtect 保护您的应用程序数据库。 这将确保您的应用程序被锁定,因此无法被删除。
使用 MemHandleLock 和 MemHandleSetOwner 锁定您的代码段(将所有者设置为 0)。 这将确保您的代码被加载到内存中并且不会被移动。
注册一些通知。 例如,sysNotifyIdleTimeEvent 是一个很好的通知,可用于执行一些定期后台处理。
设置完成后,您可以退出警报启动代码,然后等待通知触发。 然后,当调用通知处理程序时,您将执行所有后台处理。
还要确保,如果您分配任何系统对象(内存、句柄、文件句柄等),并且您希望它们在从通知处理程序返回后保留下来,则将它们的所有者设置为 0(系统)。 否则系统会清理它们。 如果您这样做,请格外小心,避免内存和资源泄漏! 当所有者设置为 0 时,它们永远不会被清理!
要离开后台模式,只需执行相反的操作:取消注册通知、解锁代码段并取消保护应用程序数据库。
如果您在后台执行任何网络操作,请确保将套接字设置为非阻塞模式并正确处理! 否则你会阻塞前台应用程序并导致问题。
This is possible to do but very difficult. There are several steps you'll have to take.
First off, this only works on Palm OS 5 and is sketchy on some of the early Palm OS 5 devices. The latest devices are better but not perfect.
Next, you will need to create an alarm for your application using AlmSetAlarm. This is how you accomplish the "every X minutes or hours" part.
When the alarm fires, your application will get a sysAppLaunchCmdAlarmTriggered launch code, even if it's not already running. If you only want to do something simple and quick, you can do it in response to the launch code and you're done.
After you do your stuff in the alarm launch code, be sure to set up the next alarm so that you continue to be called.
Important notes: You cannot access global variables when responding this launch code! Depending on the setup in your compiler, you probably also won't be able to access certain C++ features, like virtual functions (which internally use global variables). There is a setting you can set in Codewarrior that will help with this, but I'm not too familiar with it. You should architect your code so that it doesn't need globals; for example, you can use FtrSet and FtrGet to store bits of global data that you might need. Finally, you will only be able to access a single 64KB code segment of 68000 machine code. Inter-segment jumps don't work properly without globals set up.
You can get around a lot of these restrictions by moving the majority of your code to a PNOlet, but that's an entirely different and more complicated topic.
If you want to do something more complicated that could take a while (e.g. load a web page or download email), it is strongly recommended not to do it during the alarm launch code. You could do something in the sysAppLaunchCmdDisplayAlarm launch code and display a form to the user allowing them to cancel. But this is bound to get annoying quickly.
Better for the user experience (but much more complicated) is to become a background application. This is a bit of black magic and is not really well supported, but it is possible. There are basically three steps to becoming a background application:
Protect your application database using DmDatabaseProtect. This will ensure that your application is locked down so it can't be deleted.
Lock your code segment using MemHandleLock and MemHandleSetOwner (set the owner to 0). This will ensure that your code is loaded into memory and won't be moved.
Register for some notifications. For example, the sysNotifyIdleTimeEvent is a great notification to use to do some periodic background processing.
Once you set this up, you can exit from the alarm launch code and then wait for your notifications to fire. You will then do all of your background processing when your notification handlers are called.
Also make sure that if you allocate any system objects (memory, handles, file handles, etc.), you set their owner to 0 (system) if you expect them to persist after you return from your notification handler. Otherwise the system will clean them up. If you do this, be super careful to avoid memory and resource leaks!! They will never get cleaned up when the owner is set to 0!
To leave background mode, simply do the reverse: unregister for notifications, unlock your code segment, and unprotect your application database.
If you do any network operations in the background, be sure that you set the sockets to non-blocking mode and deal correctly with that! Otherwise you will block the foreground application and cause problems.