I have a class which extends android.app.Application, which I use to persist global state around my application.

I want to start off a service when my application starts, so inside the constructor of this GlobalState class I try to create an intent and start a service, but I can't create an intent because I can't get hold of Context

I've tried using getApplicationContext(), but this throws a null pointer exception.

java.lang.NullPointerException
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)
at android.content.ComponentName.(ComponentName.java:75)
at android.content.Intent.(Intent.java:2551)
at com.jameselsey.apps.cercademi.domain.GlobalState.(GlobalState.java:48)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1479)
at android.app.Instrumentation.newApplication(Instrumentation.java:957)
at android.app.Instrumentation.newApplication(Instrumentation.java:942)
at android.app.ActivityThread$PackageInfo.makeApplication(ActivityThread.java:518)

"I want to start off a service when my application starts" -- I doubt that your users want you to do this. Task killers and the force-stop capability in Settings arose because of developers mis-using services, and I am willing to bet that a "DatabaseManager" does not need to be a service, let alone one running "when my application starts" (whatever that concept means in Android).
–
CommonsWareJun 26 '11 at 10:15

@CommonsWare When my app starts, I want to read some details from a SQLite instance then make use of the Geocode API, both potentially time consuming tasks. I wanted to create a service that starts just before the splash screen so it has a few seconds to get a head start so to speak. Can you suggest any better ways of doing this?
–
JimmyJun 27 '11 at 9:07

1

Have the splash screen start the IntentService.
–
CommonsWareJun 27 '11 at 10:48

3 Answers
3

For Activity, Service, ContentProvider and Application, you should not do anything in the constructor. The first place you should do work, when you know the object is initialized and ready for use, is onCreate().

Further, please think again about "I want to start off a service when my application starts." What you code is doing here is trying to start a service when your process happens to start. I really don't think you want that. You want this service to start because you happened to receive a broadcast in the background?

If you just want to do some first time init, my recommendation is to not use Application at all. Have a singleton that can be retrieved when it is needed. Then your init happens at the point it is actually needed. There is no need for this to be associated with a service; you can just make a thread. The only reason to use a Service is to tell the system "my app is busy doing background work that the user cares about, please try not to kill me."

Base class for those who need to maintain global application state. You can provide your own
implementation by specifying its name in your AndroidManifest.xml's <application>
tag, which will cause that class to be instantiated for you when the process for your
application/package is created.

Four times out of ten, an Android developer's force close problem is forgetting to modify the Android manifest. (I totally made up that statistic).

Application extends Context, so you should be able to pass it.

However, extending Application is not the most resource-efficient way of doing this. To explain it more succinctly, here's a nother quote from the same page:

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.