Why?
Assuming from MainActivity
(the first activity launch when app start) we launch AnotherActivity
, then the application when into background/idle (because we press home button) and the application got killed because of low memory. When we try to open the app again, Android will try to resume from AnotherActivity
without launching MainActivity
.
What's the problem?
Ideally, we would do application wide initialization code at Application.onCreate. Sometimes it is not possible to do so.
For example, I build an app which prompt for user input password in MainActivity
to create an crypto object to be used for subsequent encryption and decryption. Due to the security nature of the app, I cannot store the password on disk. When the app got killed while idling, I lost the user input password (or crypto object). If I am not aware that this scenario might happen and resume at AnotherActivity
, I will get a null password (or ctypto object) which I didn't handle.
How to solve this?
We need a mechanism to check if the initalization at MainActivity
is executed properly. If it hasn't, we should launch MainAcvity
immediately.
Below is my singleton class for the checking.
object App { fun checkRestartMainActivity(context: AppCompatActivity): Boolean { if (CRYPTO_INSTANCE == null) { // check if initialization is done properly val intent = Intent(context, MainActivity::class.java) // clear all activty history/stack and return to MainActivity intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK; context.startActivity(intent) context.finish() return true } return false }}
Put the above checking in all Activity.onCreate
(except MainActivity
).
class AnotherActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (App.checkRestartMainActivity(this)) { return } }}
NOTE: If you are using lateinit
and clean up object/connection at onDestroy
, beware of bumping into UninitializedPropertyAccessException
.
If you don't want to create a singleton object, you can use companion object
in MainActivity
to check for initialization.
class MainActivity : AppCompatActivity() { companion object { val INITIALIZED: Boolean = false } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) INITIALIZED = true }}
class AnotherActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (!MainActivity.INITIALIZED) { // launch MainActiviy return } }}
References: