所有这一切都运行正常,但偶尔会在5-6天之后连续运行应用程序崩溃(目前我不知道为什么,因为我现在无法接通电话).这不是连接问题(我知道)并且手机仍在运行(插入AC).我唯一能想到的是应用程序已关闭.
我不认为这是由于一个错误,因为prew调试不会给我任何错误.
所以我必须假设androID已经杀死了这个活动(系统需要更多的内存?),而且由于图像解释没有办法支持它.
但我有一个疑问:在我的应用程序中,活动并不重要,因为所有工作都是由服务完成的.服务本身由报警管理器调用,在两次调用之间的时间内,服务由StopSelf()终止.
在我的情况下系统可能会杀死我的警报管理器服务时间表?
如何让Alarm Manager永远启动服务?
(注意:目前还有一个WAKE LOCK,但这只考虑服务的执行!我希望您已经了解该服务每隔x分钟被警报管理器调用而不是终止…我想执行此 *** 作无限期)
[我没有发布源代码因为太长了]
解决方法 Lork,在与自己的类似问题搏斗之后,我可能会为您提供一些建议.我假设您使用AndroID设备作为一种远程“嵌入式控制器”,它以最少的用户交互执行其功能.我相信你在那里95%,只需要做一些轻微的架构改变.由于您没有提供代码,我只是用抽象的术语解释而不是给出代码示例.
CommonsWare是正确的,你需要使用AlarmManager,但我怀疑你已经知道了.
首先是几个背景评论,只是为了确保一切都是可以理解的.
AlarmManager创建的警报存在于系统级别,即它们可以存在于创建它们的活动和应用程序的生命周期之外.如果你设置了一个警报,但是如果你的应用程序改变了状态(例如在它被销毁之后)就不想让它关闭,那么你可以使用alarmManager.cancel(pendingIntent)取消它 – 只需创建意图和警报管理器相同的参数和AndroID将匹配警报).
类似地,broadcastReceivers在系统级别注册(至少如果它们在manifest.xml中声明),并且可以存在于创建它们的活动和应用程序的生命周期之外.同样,如果您希望确保broadcastReceiver不会响应应用程序更改状态后发生的事件(例如在销毁之后),则需要在其中显式取消注册代码.如果以编程方式注册,则使用context.unregisterReceiver(broadcastReceiver);如果它在Manifest中静态注册它不那么容易 – 你将不得不使用PackageManager和Componentname检索接收器(参见:Android – how to unregister a receiver created in the manifest?) – 并记住,如果你需要它,你将需要重新启用接收器.
你说你已经设置了闹钟.确保为警报类型指定ELAPSED_REALTIME_WAKEUP或RTC_WAKUP,以确保即使手机处于“睡眠”模式也能运行它.
您还说您已经创建了相关的broadcastReceiver来处理警报事件. broadcastReceiver应该完成最少的工作,因此您应该在单独的线程中或通过启动服务来处理任何处理.您选择启动服务并在完成后使用stopSelf()终止它,以便它不会耗尽系统资源.到现在为止还挺好.
这在应用程序运行时很好,但是当您需要无限期可靠运行的东西时,您需要确保管理已暂停的“异常”情况,设备正在“休眠”,应用程序已崩溃/已终止,或者设备已重新启动(以及您可能想到的任何其他异常情况).以下是我需要解决的问题:
第一:WakeLock仅在broadcastReceiver的onReceive()方法的持续时间内得到保证.终止后,即使您的服务尚未启动甚至完成,设备也可以返回“睡眠”状态,因此您需要创建一个WakeLock,将其传递给服务并在停止服务之前将其释放. (注意:对于您的应用程序,您需要PARTIAL_WAKE_LOCK).使用WakeLocks时要非常小心 – 确保只在最短的时间内按住WakeLock并确保将其释放,因为它的使用会导致电池耗尽过多.有关使用WakeLocks的示例,请参阅http://www.netmite.com/android/mydroid/development/pdk/docs/power_management.html.
第二:如果您在代码中重置警报(而不是定义自动重复警报),请在broadcastReceiver的OnReceive()方法中执行此 *** 作,或者作为您已启动的服务中的第一项 – 这将确保警报重复,无论应用程序或设备的状态如何.
第三:确保您使用的任何上下文都是非空值.您可以使用getApplicationContext()动态获取服务中的上下文.否则,这可以通过将Context从您的应用程序传递到警报并确保它一直通过broadcastReceiver以及相关的线程和服务来实现.如果您在应用程序中静态存储了Context,以便可以在任何地方检索它,那么如果应用程序已终止,则返回null值.如果您使用Context(例如,检索资源,访问数据库等),并且它为null,则会导致空指针异常,并且Service或broadcastReceiver将崩溃.我相信这是您的应用程序终止时广播接收器无法工作的最可能原因.
第四:您可能希望在您的服务或broadcastReceiver完全限定(.R.drawable.icon)中引用ResourceID(例如R.drawable.icon)或从传递的Context生成.我还没有发现这是必要的,但我怀疑这可能是谨慎的.
第五:实现单独的broadcastReceiver来处理设备重启场景(ON_BOOT_COMPLETE事件).如果合适,您可以让此接收器重新启动应用程序,或者它可以启动服务以检查您的应用程序是否应该处于活动状态,设置任何所需参数并设置相关警报,然后使用stopSelf()终止它,或者只是再次设置闹钟并让接收器处理它.请记住确保服务在其持续时间内具有WakeLock,并在完成后释放WakeLock.如果您不只是重新启动应用程序或服务(声明为应用程序的一部分),那么您还应该在broadcastReceiver中静态存储正确的Context作为类属性(如果需要),以便可以访问它资源.
您可能希望考虑的其他几件事:
由于您的设置是远程的,我会认真考虑在sqlite数据库表中存储任何持久数据.这将确保数据在应用程序终止和设备重新启动之间可以恢复,而无需重新生成它.
如果您的应用程序与服务器服务通信,请考虑使用推送通知进行服务器启动的通信,而不是让应用程序定期轮询.推送通知还可用于“唤醒和启动服务和应用程序”,因此可以用作远程机制的一部分来查询设备和应用程序的状态.这种方法也更节能和及时.
在代码中的关键点将信息发布到LogCat以进行调试.如果应用程序终止,则adb停止跟踪为接收器和服务运行的源代码,但LogCat继续运行,因此可用于检查代码和变量值的路径.
其他人可能有更好的方法来解决这些问题或其他一些指针(我当然很乐意看到其他意见),但我希望这些想法是有帮助的,祝你好运!
总结以上是内存溢出为你收集整理的Android应用程序生命周期:也许它无限?全部内容,希望文章能够帮你解决Android应用程序生命周期:也许它无限?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)