Skip to content

Instantly share code, notes, and snippets.

@illarionov
Last active January 17, 2022 12:17
Show Gist options
  • Save illarionov/bfa53e14321a8e85a102f24bed88c578 to your computer and use it in GitHub Desktop.
Save illarionov/bfa53e14321a8e85a102f24bed88c578 to your computer and use it in GitHub Desktop.
Demonstration that the Android can destroy background activities on memory pressure without restarting the application
/**
* Demonstration that the Android can destroy background activities on memory pressure without restarting
* the application
https://cs.android.com/android/platform/superproject/+/android-12.0.0_r4:frameworks/base/core/java/android/app/ActivityThread.java;l=7534
*/
const val ARG_ACTIVITY_NO = "ARG_ACTIVITY_NO"
const val TAG = "MainActivity"
val gcThresholds = GcActivityMemoryThresholds()
class MainActivity : AppCompatActivity() {
val handler = Handler(Looper.getMainLooper())
var activityNo: Int = -1
val garbage: MutableList<ByteArray> = LinkedList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityNo = intent.getIntExtra(ARG_ACTIVITY_NO, 1);
Log.i(TAG, "onCreate: $activityNo")
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.textView).text = "activity $activityNo"
if (activityNo == 1) {
while (gcThresholds.usedMemory <= gcThresholds.threshold) {
garbage += ByteArray(1024 * 1024)
}
} else {
repeat(5 * 1024) {
garbage += ByteArray(1024)
}
}
if (activityNo < 10) {
handler.postDelayed({
startActivity(Intent(this@MainActivity, MainActivity::class.java).apply {
putExtra(ARG_ACTIVITY_NO, activityNo + 1);
})
}, 1000)
}
}
override fun onStart() {
super.onStart()
Log.i(TAG, "onStart: $activityNo; Memory; $gcThresholds")
}
override fun onStop() {
super.onStop()
Log.i(TAG, "onStop: $activityNo")
}
override fun onDestroy() {
super.onDestroy()
Log.i(TAG, "ON_DESTROY: $activityNo")
handler.removeCallbacksAndMessages(null)
}
}
class GcActivityMemoryThresholds() {
val threshold: Long = run {
val runtime = Runtime.getRuntime()
val dalvikMax = runtime.maxMemory()
(3 * dalvikMax) / 4
}
val usedMemory: Long
get() {
val runtime = Runtime.getRuntime()
return runtime.totalMemory() - runtime.freeMemory()
}
override fun toString(): String {
return "GcActivityMemoryThresholds(threshold=$threshold, usedMemory=$usedMemory)"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment