Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/217.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由于堆碎片导致服务崩溃的Android活动_Android_Service_Android Activity_Heap_Fragmentation - Fatal编程技术网

由于堆碎片导致服务崩溃的Android活动

由于堆碎片导致服务崩溃的Android活动,android,service,android-activity,heap,fragmentation,Android,Service,Android Activity,Heap,Fragmentation,我有一个Android应用程序(活动),它也有相应的服务。服务由活动启动,即使活动停止,服务也应持续运行。当活动再次启动时,它可以绑定到服务并查询它 有时,操作系统会破坏并创建活动。这不应该影响任何事情,活动应该被重新创建,并且能够再次绑定到服务。这基本上是可行的 然而 我发现Dalvik VM堆和本机堆都是非压缩的,因此大小会不断增加,直到活动耗尽内存并崩溃(即使总内存使用量实际上是恒定的且不会泄漏)。由于在创建过程中进行了大量分配,因此销毁和重新创建活动会大大加剧这种情况 这几乎保证了活动在

我有一个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-您可以通过在清单中为服务指定一个值来验证您的假设。这将使该服务与应用程序的活动分开。