0

Sometimes my app is forced to quit and then later Android restarts it just to run a scheduled job. I can't find a callback that would correspond to this scenario: that my app got killed in the meantime, so I have to restore all my retained state.

I want to avoid a proliferation of entry points where I have to re-check whether everything is still in place. I already have onUpdate() for a widget, onCreate() for the main activity, onResume() for a view fragment, and onStartJob() for the scheduled job. Any of them could be the first thing to be called after the app is killed, so in all these places I have to repeat the initialization code.

Is there a single point where I can register a callback that will re-initialize my app state?

To be specific, I have a JobService:

class RefreshImageService : JobService() {
    override fun onStartJob(params: JobParameters): Boolean {
        MyLog.i("RefreshImageService start job")
        updateWidgetAndScheduleNext(applicationContext)
        return true
    }

    override fun onStopJob(params: JobParameters): Boolean {
        MyLog.i("RefreshImageService stop job")
        return true
    }
}

The updateWidgetAndScheduleNext() call involves some state I have:

private data class TimestampedBitmap(val bitmap : Bitmap, val timestamp : Long)

private var tsBitmap: TimestampedBitmap? = null

To compute the timestamp, I have to call into further code that has its own state; that other code is called form all the entry points I mentioned. I'd like to centralize my initialization code, if possible.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • "Any of them could be the first thing to be called after the app is killed, so in all these places I have to repeat the initialization code" -- convert your "retained state" and "initialization code" into a lazy-initialized cache, with a callback or Observable to get the cached information. Nowadays, that might be wrapped up in a singleton (or dependency-injected) repository. – CommonsWare Nov 30 '17 at 19:14
  • @CommonsWare So basically, the simplest way is to get into bed with yet another framework (DI). I'm trying to keep things minimal, not yet ready for this :) – Marko Topolnik Nov 30 '17 at 19:22
  • You don't need DI. You don't need RxJava. They are options. You can accomplish the same objective with a simple callback and thread. – CommonsWare Nov 30 '17 at 19:34
  • @CommonsWare Yes, that's approximately what I'm up to now. My question was in the hope that there's a way to be notified that my state was dropped instead of having to re-check it every time. – Marko Topolnik Nov 30 '17 at 19:38
  • Um, a lazy-initialized singleton requires a single `if` check to see if a `static` field is `null`. Moreover, your lazy-initialization logic can be situation-aware, only initializing what is requested. Even if today you happen to need all of the same state in all three of your scenarios (app widget, activity UI, `JobService`), that's unlikely to be the case over the long term. You're welcome to centralize stuff using `Application#onCreate()`, but then you don't know *why* your process was created, so you're flying blind in terms of what needs to be initialized. – CommonsWare Nov 30 '17 at 19:42
  • The point behind lazy initialization is to not waste device RAM, CPU, and battery doing things that wind up not being necessary during the life of that process. For instance, for an app widget update, that process might not live very long. – CommonsWare Nov 30 '17 at 19:43
  • @CommonsWare So `Application#onCreate()` may be the thing I'm looking for. My init concerns functions that OCR my image bitmaps, I need them everywhere. I think this is a good fit for app-level init, thanks. – Marko Topolnik Nov 30 '17 at 19:46
  • @CommonsWare There's one thing I failed to mention: my init requires `context`, this is why it's inconvenient to initialize it from a general facility. But I'm probably just missing another bit, which is how to access the app context "out of the blue", from some static state. – Marko Topolnik Nov 30 '17 at 19:49
  • You pass a `Context` into the method(s) that retrieve the cached data, or use a DI system that can inject a `Context`. All of your entry points have a `Context`. – CommonsWare Nov 30 '17 at 19:52
  • @CommonsWare Yes, that proliferation of the concern of initializing is what I'm trying to get rid of. Anyway, thanks for your tips. – Marko Topolnik Nov 30 '17 at 19:59

0 Answers0