6

I have a project (in Eclipse) which I've turned into an Android Project Library so as to re-use some of the code in another similar project. I think I've shot myself in the foot however as I'm getting the error:

Unable to start activity ComponentInfo{com.test.scroller1/com.lib.scrolltest.ScrollTestActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.lib.scrolltest.resAppVars

com.lib.scrolltest is my Project Library which instantiates a class extending Application (resAppVars). In the onCreate() method I call:

mRav = (resAppVars) getApplicationContext ();

This way, I can use methods in the mRav object which would otherwise be a lot of duplicated code in other classes (such as passing a query to a generic select statement which returns an ArrayList of results).

What's the problem here? It seems I've hit a limitation in the way I've implemented the Application class.

wufoo
  • 13,571
  • 12
  • 53
  • 78

2 Answers2

4

Calling getApplicationContext() returns the Application object for the current application (i.e. the application that owns the activity that onCreate() is running inside of).

Unless you're doing something strange, you don't get to pick which Application class is used. There's even a note in the documentation for Application saying not to do this:

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.

You should just create a regular shared class inside of your library project. Or if you don't have a need for the special functionality library projects offer, you can also just use a regular .jar file.

And if you need shared state, just make it a singleton. ;)

Trevor Johns
  • 15,682
  • 3
  • 55
  • 54
  • Thanks but static variables (singletons) are not the best way in Android. Static vars can be initialized to default values in some instances of the application lifecycle. http://stackoverflow.com/questions/2475978/using-static-variables-in-android http://electronicvendor.com/using-static-variables-in-android/ I appreciate you taking the time to answer however. – wufoo Dec 28 '11 at 15:06
  • 1
    As far as I know, a singleton will exist for the lifetime of your app's process. The process lives at least as long as any non-destroyed component (activity, service, etc.) within your app. – Trevor Johns Dec 28 '11 at 19:54
  • @wufoo I still don't understand why static singletons are bad. I mean, Android documentation itself says to use them instead of subclassing the Application class. How can it be so bad?? – IgorGanapolsky Aug 08 '12 at 01:01
  • 2
    As it turns out there is a bit of a schism around static variables (singletons). Some say good, some say bad. As Igor mentions, the Android docs do indeed recommend the use of statics. For those new to Android development, be aware that static variables are generally frowned upon as they can be modified anywhere and everywhere from within the application. It's a concept which completely breaks modular programming design and almost always ends up being a maintenance headache. – wufoo Feb 19 '14 at 16:42
  • 1
    I try to avoid static objects, thinking with a java background will make you believe these static objects will live forever during app lifecycle; however when used in an Android app, the SO can delete your static objects whenever the app is in background and device has low memory warnings. The problem is that it can free the static classes but sometimes it leaves the last activity in memory; when the user opens the app, the last activity runs but the static objects are no longer there so there are huge possibilities to get a crash. So be careful and try to prevent this in your singleton code. – htafoya Jun 02 '14 at 12:06
3

Although this is a very old post. I encountered the same problem and solved it. So I thought I'll post the solution for everyone.

It turns out that I forgot to declare the subclassed application name in the manifest file. The android:name should point to the extended app class, even if it is defined in the referenced library.

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:name="com.example.lib.MyApp">

After I added that I could use the extended app with (<cast>) getApplication() anywhere in my project.

ilomambo
  • 8,290
  • 12
  • 57
  • 106