2016-01-19 81 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