由于堆碎片导致服务崩溃的Android活动
我有一个Android应用程序(活动),它也有相应的服务。服务由活动启动,即使活动停止,服务也应持续运行。当活动再次启动时,它可以绑定到服务并查询它 有时,操作系统会破坏并创建活动。这不应该影响任何事情,活动应该被重新创建,并且能够再次绑定到服务。这基本上是可行的 然而 我发现Dalvik VM堆和本机堆都是非压缩的,因此大小会不断增加,直到活动耗尽内存并崩溃(即使总内存使用量实际上是恒定的且不会泄漏)。由于在创建过程中进行了大量分配,因此销毁和重新创建活动会大大加剧这种情况 这几乎保证了活动在多次重新启动后会崩溃。这并没有让我太烦恼,但是接下来发生的事情是服务也崩溃了,因为它是同一个应用程序的一部分。该服务包含一些重要数据,这些数据在崩溃期间丢失 我对如何解决这个问题有什么建议感兴趣 有没有办法将服务与活动分离(这样当活动崩溃时,它不会同时崩溃服务),但服务和活动仍在同一个应用程序中由于堆碎片导致服务崩溃的Android活动,android,service,android-activity,heap,fragmentation,Android,Service,Android Activity,Heap,Fragmentation,我有一个Android应用程序(活动),它也有相应的服务。服务由活动启动,即使活动停止,服务也应持续运行。当活动再次启动时,它可以绑定到服务并查询它 有时,操作系统会破坏并创建活动。这不应该影响任何事情,活动应该被重新创建,并且能够再次绑定到服务。这基本上是可行的 然而 我发现Dalvik VM堆和本机堆都是非压缩的,因此大小会不断增加,直到活动耗尽内存并崩溃(即使总内存使用量实际上是恒定的且不会泄漏)。由于在创建过程中进行了大量分配,因此销毁和重新创建活动会大大加剧这种情况 这几乎保证了活动在
我可以保留服务数据,但这需要多次访问数据库,不利于节省电池。听起来您的服务正在维护对您已停止活动的引用。您应该使用已启动的服务,而不是绑定的服务。有关差异以及如何使用每个差异的详细信息,请参阅上的指南主题
如果您想使用绑定服务(也就是说,由于某种原因,您确实需要使用
bindService()
),那么请确保在活动结束之前调用unbindService()
。请注意,当最后一个活动解除绑定时,服务将暂停。听起来您的服务正在维护对已失效活动的引用。您应该使用已启动的服务,而不是绑定的服务。有关差异以及如何使用每个差异的详细信息,请参阅上的指南主题
如果您想使用绑定服务(也就是说,由于某种原因,您确实需要使用
bindService()
),那么请确保在活动结束之前调用unbindService()
。请注意,当最后一个活动解除绑定时,服务将暂停。您应该在清单中指定服务“进程名称”,您可以用“:”或小写字符开始名称。引述:
如果分配给此属性的名称以冒号(“:”)开头,则
当需要时,将创建应用程序专用的新进程
服务在这个过程中运行。如果进程名称以
一个小写字符,服务将在
该名称,前提是它有权这样做
清单中有一个例子
<service android:name=".services.OfficeService"
android:process=":myProcess" />
您应该在清单中指定服务“进程名称”,您可以用“:”或小写字符开始名称。引述: 如果分配给此属性的名称以冒号(“:”)开头,则 当需要时,将创建应用程序专用的新进程 服务在这个过程中运行。如果进程名称以 一个小写字符,服务将在 该名称,前提是它有权这样做 清单中有一个例子
<service android:name=".services.OfficeService"
android:process=":myProcess" />
我需要一个既已启动又已绑定的服务,实际上我调用了unbindService()。我认为问题在于,由于服务仍在运行(这是预期的),因此当前堆仍处于活动状态。当活动重新启动时,它使用与服务相同的堆,该堆现在已经严重碎片化。@chris-您可以通过在清单中为服务指定一个值来验证您的假设。这将使该服务与应用程序的活动处于一个单独的进程中。我需要一个既已启动又已绑定的服务,实际上我调用了unbindService()。我认为问题在于,由于服务仍在运行(这是预期的),因此当前堆仍处于活动状态。当活动重新启动时,它使用与服务相同的堆,该堆现在已经严重碎片化。@chris-您可以通过在清单中为服务指定一个值来验证您的假设。这将使该服务与应用程序的活动分开。