2016-01-19 33 views
1

我正在编写一个Android NDK应用程序,它由一个基于android.app.NativeActivity类的几行Java胶水代码组成的C中的大型平台无关核心组成。除了让我头痛的事情之外,这个工作真的很好。开始与所有全局变量归零的应用程序

问题是,Android应用程序在调用ANativeActivity_finish()时并未真正退出,而是它们只是处于某种空闲状态和AFAIU状态,它们只有在Android需要这些资源时才会被杀死。

这个Android的特性对我来说是一个巨大的问题,因为我的C内核使用了很多全局变量,并且当我的C内核运行其关闭代码时它们不会重置为0。因此,当Android在关闭后启动我的应用程序时,所有全局变量都包含一些随机状态,从上次运行应用程序而不是0.

这在所有支持的桌面系统上都不是问题我的程序(Win32,Mac OS,Linux),因为在这些系统程序可以真正退出。但在Android上,这是根本不同的。是的,我知道全局变量很糟糕,并且在完成它们之后我应该将它们重置为0,但是我们正在讨论一个已经开发了近20年的非常大的C核,因此需要大量的努力清理这一切只是为了Android。

这就是为什么我想问一下,是否有某种方式可以强制Android总是将所有全局变量全部清零,就像应用程序第一次启动时一样。

我已经做了一些研究和AFAICS唯一的方法来做到这一点将是真正杀死我的应用程序使用android.os.Process.killProcess(),但这看起来像一个蛮力的方法。在启动我的应用程序时,没有其他方法可以始终获得归零的全局变量吗?

回答

2

初始归零由操作系统执行 - 变量存储占用新映射的页面。没有“调零需要调零的东西”内部函数来调用。

你有两种基本方法:

  1. 让Android应用程序的工作像它在其他平台上,并手动终止应用强行重新加载。
  2. 让您的应用程序像Android一样工作,并且不会像停止时​​完全关闭一样。换句话说,千万不要运行你的关机代码。当应用程序暂停时,您仍然需要释放大量资源,但这应该比将所有内容全部关闭的负担少一些。

#2的可行方法取决于代码的性质。

是的,我知道,全局变量是不好的,当他们完成了,我应该将其重置为0,但

如果你绝对必须使用全局变量,创建一个单一的全球性结构和桩万事成它,所以如果你需要重置它或在调试器中转储所有的状态,很容易找到所有的东西。这并不理想,但比寻找分散的全局变量和(天堂发现)静态局部变得更容易管理。

+0

谢谢,有关如何“正常”手动杀死应用程序的确切答案?我已经做了一些研究,似乎有很多不同的建议,例如'System.exit()','android.os.Process。killProcess()',新的API 21'finishAndRemoveTask()'和'finishAffinity()',但到目前为止我还没有找到明确的答案如何手动杀死应用程序。我试过System.exit(),但这会导致LogCat(“消费者关闭的输入通道或发生错误”)的某些警告消息,有时还会出现“WIN DEATH”警告,似乎这不是一个好的解决方案... – Andreas

+0

请记住,您不需要杀死* app *,您需要杀死它正在运行的*进程*,因为您需要系统加载程序来有效地重置全局变量。如果有其他应用程序在同一个进程中运行,您别无选择,只能杀死这些应用程序。考虑到这一点,'killProcess()'方法(发送SIGKILL,与低内存杀手相同)是适当的。 'System.exit()'的优点是它会执行已经注册的任何“退出”处理程序,但这通常与Android无关,因为应用程序不会退出。 – fadden

+0

好的,谢谢。它工作,虽然在退出时我有时会得到LogCat消息,说明JavaBinder或消费者关闭的输入通道的FAILED BINDER TRANSACTION,或者发生错误或试图从InputDispatcher注销未成功的输入通道。我认为这些只是因为我的应用程序突然消失,因为Android没有期望的killProcess()? – Andreas