当安卓应用更新时,会发生什么?

12

当Play Store更新应用程序时,设备上的工作流程是什么?如果用户同时正在使用该应用程序会发生什么?

我之所以这样问,是因为我们有一些崩溃情况,在此情况下找不到字符串ID,当我们查看APK时,字符串资源在两个版本中都可用但是在崩溃报告中报告的十六进制ID在旧版本apk中被找到而不是新版本中。这很奇怪。

这使我们认为,Play Store可能在应用程序运行时更新了应用程序的文件和资源,然后当它查找字符串资源以加载某些内容时,使用了来自内存中的旧ID,并且当然在新更新的文件中找不到它...从而导致ResourceNotFound异常。

这是否可能? 我本以为不可能,但我们在APK中查看时发现,崩溃报告中匹配的ID与新推送的ID不同而是匹配旧的资源ID。


3
据我所知,在更新应用程序之前,必须停止应用程序进程。@ShobhitPuri-即时发布和更新并没有解决Google Play客户端在设备上运行的应用程序问题。 - Ted Hopp
@TedHopp 确认这一点。我一直在使用应用程序进行更新,它们总是自动关闭。 - Michael Stubbs
我之前也遇到了类似的问题。尽管应用程序在更新时会经历onDestroy/onCreate/onResume,但它不会重新加载全局静态变量。因此,如果您声明了一个全局静态变量,例如static int resId = R.id.something;,只需再次将其放入onCreate中(resId=R.id.something;)。 - stefple
@stefple - 听起来就像我的行为一样,只是我们因为它正在寻找旧的字符串资源而导致崩溃。 我们肯定不应该强制Android重新加载我们的res / *东西吧? - Matthew Runo
3个回答

2
根据我的研究,似乎需要关闭应用程序才能更新文件。一旦关闭,Google Play只更新APK中发生更改的部分,以节省时间和成本。
我找到了几篇论坛帖子,教您如何从刷入的ROM中回滚应用程序选项(这在已Root设备上经常发生)。也许用户尝试在接收更新后回滚。或者,在崩溃中引用的ID位于未更新的apk的某个部分。
来源: 更新通知 Android应用更新时会发生什么 Google Play可节省时间和成本

我同意应用程序在更新时应该关闭,但是如果这样做,我怎么能从新应用程序版本的崩溃日志中获取仅存在于旧R.java中的String ID呢? - Matthew Runo
这就是问题所在,我想。它一定与R.java存储ID的方式有关,或者可能是一个未更新的文件引用了该字符串ID,而它不再包含在新的R.java中,因此出现了错误。您是否能够重现此问题,或者在您的用户集中发生了大规模的问题?还是这只是一个用户的一次性崩溃? - Phoenix
这种情况发生在大约30万次应用程序升级中,涉及数百次崩溃。这不是一次性事件。它报告在2.3.x Android版本以及4.1.x版本的平板电脑和手机上。 - Matthew Runo
在这种情况下,我想象,根据“智能更新”方案,您的apk包含一个文件,引用了旧的R.java ID,并且由于未被修改,因此未与其他文件一起更新。考虑到受影响用户的范围,那将是我最好的猜测。当然,这仅基于我对通过Google Play进行更新过程的工作知识以及我极其有限的了解您的应用程序。 - Phoenix

1
我记得遇到过类似的问题——在我的情况下,我们通过用户偏好设置存储资源标识符(甚至是序列化的枚举值)。一旦我们的应用程序更新了(有新的枚举值、新的资源),旧值就会从用户偏好设置中加载并传递到代码中,导致崩溃。
也许这不是你的问题,但检查一下是否存储/加载了不存在的资源标识符仍然值得一试。

1
如果用户在更新应用程序时同时使用该应用程序,Linux文件系统允许上述行为。持有文件打开状态的进程(例如运行中的应用程序可执行文件)将使可执行映像保留在内存中,即使磁盘上的可执行文件已经更新。这允许新的apk放置并解压缩,而旧的exe映像仍然保存在内存中。
资源文件往往是懒加载的,因此在内存中导航旧映像会查找资源,并可能从新解压的应用程序中加载资源。该资源可能与旧应用程序不兼容并导致崩溃。

除非安卓应用程序正在运行并需要安装更新,否则它不会关闭应用程序。 - Afzal N
这里的“smoking gun”似乎是我们新应用程序版本中的崩溃报告,其中包含仅存在于旧版本R.java中的String ID =\ - Matthew Runo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接