Is it okay, resource wise, to have an infinite loop refresh a TextView (every n seconds) with a string from context.getString()?

Viewed 1146

So, I have this function:

inline fun runInLoop(intervalInMillis : Long = 1_000, crossinline function : suspend () -> Unit) {
    CoroutineScope(Dispatchers.Main).launch {
        while (true) {
            function.invoke()
            delay(intervalInMillis)
        }
    }
}

And I use it like so:

Time.runInLoop(10_000L) {
    binding.timeCreatedTextView.text = mContext.getString(R.string.time_created, 
    Time.unixToRelativeTime(item.timeCreated))
}

Basically, I use this function to loop every one second to refresh "timeCreatedTextView"s with DateUtils.getRelativeTimeSpanString(), and that is used the most in RecyclerView rows, so multiple infinite loops will be running on a coroutine in the background.

My question is, is anything that I'm doing potential source for memory leaks or high memory usages, since I'm using DateUtils to get the relative time, or doing string formatting every one second for however long the view is on screan?

1 Answers

You are creating a custom CoroutineScope. That is fine, but then it is your job to indicate when that scope is no longer needed, so it stops running your infinite-loop coroutines. Right now, you do not appear to be doing that.

A better solution is to use a CoroutineScope tied to the lifetime of your UI. Since you are using a DialogFragment, the viewLifecycleScope extension property on Fragment would be a likely choice. Then, your coroutines will be cleaned up when the fragment is destroyed. You might use that scope directly, or you might still create your own custom scope, but with viewLifecycleScope as a parent, so you can control individual timers (cancelling them if they are no longer needed) while still getting lifecycle awareness.

Related