19

Android newbee here, I have some code that I want to run when my android app first starts up. It checks the version of the local database and downloads a new version if the current version is out of date. I have been sticking it in the oncreate of my first activity, pretty sure there has to be a better place to put this. Any recommendations of somewhere I can put it where it will get called once on startup?

tobylang
  • 363
  • 1
  • 2
  • 7
  • Why do you say there should be a better place to put startup code? OnCreate() should do exactly what you want.. – Snailer Jul 21 '12 at 16:55
  • Make a loading screen activity and add your version checking code in that. – Trung Nguyen Jul 21 '12 at 17:00
  • 2
    Snailer If I leave the code in the activity and then I need to suspend or recreate the activity then that code gets called over and over again. – tobylang Jul 21 '12 at 17:38
  • @user1509590, that happens with any `onCreate`. If you want to perform code once in your app lifetime, persist the state (e.g., to a `SharedPreferences`) and flag your code in order for it to never be called again. That's how we generate and persist, for example, UUID installation ids. – davidcesarino Jul 21 '12 at 17:43
  • Just to clear things up: I'm not saying `SharedPreferences` is (part of) the solution here. I'm addressing the OP, which seems particularly worried about having a block of code (any block of code, in theory) being run "over and over" because it's in the `Activity`, when, in fact, the Application object may be recreated more times than one particular Activity (especially "loading" Activities), if your app is constantly being terminated by the system for memory reasons. – davidcesarino Jul 21 '12 at 18:59
  • You could easily just declare a boolean "didInit" and set it to true after the version check, then in OnCreate() or OnResume() it wouldn't check again – Snailer Jul 21 '12 at 19:13

2 Answers2

39

You can write a custom Application class (extend from android.app.Application). Override onCreate to specify what happens when the application is started:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        // Do something here.
    }
}

You'll then need to register your custom class in the manifest file:

<application ... android:name="fully.qualified.MyApplication">

Edit:

In response to David Cesarino, I disagree with the purpose of the Application class. If you rely on the Activity's onCreate, then what's to stop it from becoming the same huge class of miscellaneous purposes... if you need something to happen when the application starts, you have to write that code somewhere; and the Activity would probably become more cluttered because you have to perform Activity specific logic in it as well. If you're worried about clutter, then separate the logic into other classes and call them from the Application. Using the SharedPreferences to determine whether or not the logic should execute seems like more of a work-around to a problem that's already been solved.

Dianne Hackborn seems to be referring to data, not logic, in which I totally agree. Static variables are much better than Application level variables... better scoping and type safety make maintainability/readability much easier.

Glen Hughes
  • 4,712
  • 2
  • 20
  • 25
  • Obviously, the `SharedPreferences` was an example to the extraneous question in the comments (it's not even part of the answer). I'm not saying that you need to persist database version (or whatever) to `SharedPreferences`, since it's already "persisted" in the database itself (for use in `onUpgrade`, *for example*). About the use of Application class to perform database checks early on, let's just agree to disagree. Thanks for the reply. – davidcesarino Jul 21 '12 at 18:51
  • Understood, I didn't mean to focus in on the `SharedPreferences` aspect of it, but rather the requirement of saying: `if (someCondition) { // Execute something. }` To me, that's what the `Application` was created for... I guess it's just two ways of looking at it, and as you said... agree to disagree. – Glen Hughes Jul 21 '12 at 19:13
  • Don't worry, no problems! :-) – davidcesarino Jul 21 '12 at 19:19
  • 1
    What's a good name for that class? As an iOS developer I would tend to name it AppDelegate, but I feel like android developers probably have a standard name for it already. – Gil Sand Mar 30 '16 at 09:13
4

First, look at the Activity lifecycle.

Answering your question, you could put code in any of those "start-up" methods, depending on what you want to do and, mostly important, when you want to trigger that. For what you asked, onCreate is the reasonable place.

I have been sticking it in the oncreate of my first activity, pretty sure there has to be a better place to put this.

And why is that? Any code has an entry point, right? In Android Activities it just happens to be onCreate (again, see above link for the full details). Besides event handling, which are responses to events happening outside the main sequence of calls, you put stuff in onCreate.

If you're concerned about the method becoming huge, then that's another problem. Abstract your code better, I say. For checking preliminary stuff, people generally provide a "Loading" activity, before starting the main activity of the app.

edited:

This is a follow up to what drumboog proposed, since my comment started to grow in complexity to be "just a comment".

Personally, I'd avoid extending the Application class for the sole reason of executing code early on, more so a code that is not that sensible in priority (versioning databases). The Application class is mostly used as an easy way to persist state between Activity'ies, not as a way to "do everything". In short, I feel the Application class is commonly abused.

For what you want, you could perfectly achieve that calling code in Activity onCreate. That reduces complexity, because I've seen people stuffing Application until it becomes a huge class of miscellaneous code purposes. And that's a no-no for maintenance, with logic problems of its own.

Besides, if you truly want another solution, completely disassociated with the UI, you should think about implementing a Service instead (but I don't think it's necessary for just that).

Both of those concerns were previously addressed by Dianne Hackborn (or what I got from her message).

davidcesarino
  • 16,160
  • 16
  • 68
  • 109
  • And even so, there are almost always better ways to persist state (statics etc.). I've counted in the fingers of one hand how many times I extended the `Application` class. – davidcesarino Jul 21 '12 at 17:40