【问题标题】:Killing app <my service> (pid 1724) because provider <my provider> is in dying process <my app>杀死应用程序 <my service> (pid 1724) 因为提供程序 <my provider> 正在终止进程 <my app>
【发布时间】:2010-09-03 12:05:26
【问题描述】:

提供程序在应用程序中实现,应用程序更新提供程序数据并触发远程服务,该服务查询提供程序以检索存储的值。应用程序在一段时间后关闭,但服务继续访问内容提供程序。在某些时候出现以下错误在logcat中抛出,远程服务崩溃。

“杀死应用程序(pid 1724),因为提供程序处于死亡进程中”

我用谷歌搜索了这个错误,但找不到关于为什么会发生这个错误的信息。

更新:在其中一个地方使用 getApplicationContext 返回的上下文而不是 Service 来获取 contentresolver 以查询内容提供者。它会导致任何问题吗?

【问题讨论】:

  • 我会稍微改变一下标题,而不是 他们可以是

标签: android


【解决方案1】:

嗯,运气不好,到目前为止还没有答案。我弄清楚是什么导致了上周的崩溃!我想我应该在这里分享。

Provider P 是在应用程序 A 中定义的,它有一个服务 S1,它会禁用包并出于某种原因终止包。现在有另一个应用程序 B 具有服务 S2 并使用提供程序 P。在某些时候服务 S1 禁用应用程序 A 包的某些组件并终止该进程,这使提供程序找到与其连接的所有进程并终止那些进程一方面,这使得应用程序 B 正在运行的进程因错误“杀死应用程序,因为提供程序处于死亡进程中而终止。

将提供程序移至新应用程序解决了该问题,以便它在自己的进程中运行解决了该问题。

【讨论】:

  • 我也遇到了同样的问题,找到了查杀app源码,如你所说:这里:android.googlesource.com/platform/frameworks/base/+/…
  • “将提供程序移动到新应用程序”?有一个android:process=":otherProcessInSameApp",您可以在清单中添加任何内容。
  • 注意:例如,由于应用程序更新,可能会杀死 App A
【解决方案2】:

TL;DR

使用不稳定的 ContentProviderClient。

这是其他作者的解释:https://stackoverflow.com/a/33562256/87383

长读

遇到同样的问题并通过下一个方法解决(解决方法):

首先你应该明白ContentResolver.registerContentObserverContentResolver.query之间的区别

所以,ContentResolver.registerContentObserver 只是将您的本地 ContentObserver 实例与 ContentService 连接起来。它是通过使用 ContentObserver.Transport 类实例(基本上是一个活页夹)创建一个“桥”并将其传递给 ContentService 来实现的。见ContentObserver.getContentObserver()

为什么它很重要?因为这些观察者不是由ActivityManagerService 管理(注册)的。

那么,ContentResolver.query 方法有什么特别之处呢?要回答这个问题,我们必须查看ContentProviderClient。因为实际查询是通过 ContentProviderClient 实例执行的,这些实例负责与远程 ContentProvider 联系。

ContentProviderClient 有两种“类型”——stableunstable不稳定客户端由您的应用程序管理。但是 stable 是由 Android 为您管理的,所以当应用程序停止时,ActivityManager knows that it's time to kill all clients

有关不稳定的内容提供程序客户端的更多详细信息,请参阅此提交:https://android.googlesource.com/platform/frameworks/base/+/6ae8d1821822296df0606c9cd1c46708cc21cb58

【讨论】:

    【解决方案3】:

    以下论坛帖子似乎相关。 https://groups.google.com/forum/?fromgroups#!topic/android-developers/7aOLy1DXdhQ

    如果有一个进程“A”运行一个内容提供者,一个进程“B”带有一个指向该内容提供者的光标(或 ContentObserver)并且进程“A”由于例如卸载“A”的包裹。

    【讨论】:

      【解决方案4】:

      试试这个解决方案:

      Context ctx = context.createPackageContext("package of the provider", Context.CONTEXT_IGNORE_SECURITY);
      cursor = ctx.getContentResolver().query(uri, null, null, null, null);
      // do something with cursor 
      

      并且在卸载包时它没有重新启动提供提供程序的主进程...

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题。就我而言,提供者不是第 3 方,而是由系统包提供。日志表明提供程序已崩溃,并且由于我的 IntentService 正在使用该提供程序,因此我的 IntentService 被杀死了。

        就我而言,我修改了我的 IntentService 以在 onStartCommand() 中返回 START_STICKY。这对我来说很有帮助,因为在我的服务被终止后,操作系统会再次重新启动我的服务并重新运行所有内容。

        从有关START_STICKY标志的文档中摘录:

        ...如果该服务的进程在启动时被杀死(之后 从onStartCommand(Intent, int, int)) 返回,然后将其留在 开始状态,但不保留此传递的意图。后来系统 将尝试重新创建服务。因为是启动状态, 它将保证在之后调用onStartCommand(Intent, int, int) 创建新的服务实例 ...

        此模式适用于将显式启动的事物,并且 停止运行任意时间段,例如服务 执行背景音乐播放。

        https://developer.android.com/reference/android/app/Service.html#START_STICKY

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-20
          • 2011-07-16
          • 2022-01-25
          • 1970-01-01
          • 2014-12-16
          • 2013-06-23
          相关资源
          最近更新 更多