-1

I have a CustomApplication extends Application class, which is registered in AndroidManifest

 <application
    ....
// Please, pay attention that I got this in my Manifest
    android:name=".CustomApplication"> 

And at different part of my application, both some activities and services I do getApplication()/getApplicationContext() then cast it to CustomApplication and it crashes in production on a variety of devices/sdk versions(beginning at android 6) due to a class cast exception. Caused by: java.lang.ClassCastException

Example:

class CustomApplication extends Application{
...
public static CustomApplication with(Context context) {
       return (CustomApplication) context.getApplicationContext(); //crashes here
   }
}

and service example:

class CustomService extends IntentService{
...
@Override
rotected void onHandleIntent(@Nullable Intent intent) {
        CustomApplication app = CustomApplication.from(getApplication());
        // tried getApplicationContext() also
}
}

and activity example:

class CustomActivity extends AppCompatActivity{
...
@Override
protected void onCreate(...){
   CustomApplication app = CustomApplication.with(this);
}

What I've tried:

  • Tried services with different process=":process"
  • Tried deep linking with different launchModes
  • Tried activities with taskAffinity
  • launching from push notifications
  • process cleaning with system tray(on device), ps kill int adb shell

nothing helps me to reproduce an issue on emulator

I don't use Instant Run also (never used it)

Please don't provide me with suggests of using static application context instance

Alex
  • 1,416
  • 1
  • 14
  • 24

2 Answers2

0

You can keep a static reference of your CustomApplication like below. You don't need to cast in the following way.

public class CustomApplication extends Application {
    private static CustomApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();

        instance = this;
    }

    public static CustomApplication getContext() {
        return instance;
    }
}

Then call CustomApplication.getContext();

ARiF
  • 1,079
  • 10
  • 23
  • I'm here to find out why .applicationContext cannot be casted to CustomApplication class. Cause it's going to clarify me a lot of android internal processes – Alex Oct 16 '17 at 13:46
0

You need to define your custom application in the manifest as follow:

<application
    ....
    android:name="my.package.path.CustomApplication"> 

    ... activities ....

 </application>

Also, you are getting an instance of a class that extends Application, not Context, that being said you should call this the following way:

CustomApplication customApplication;
customApplication = (CustomApplication)getApplication();

What you might have to apply in case you have BroadcastReceiver(No context available) is:

customApplication = (CustomApplication)getApplicationContext().getApplication();
Ricardo
  • 9,136
  • 3
  • 29
  • 35
  • I'm just giving you a full example in how you should use it. Try out what I've posted and you will see it will work. – Ricardo Oct 16 '17 at 14:09
  • it's been there for like 4 years already. App in production has 1 million monthly active users – Alex Oct 16 '17 at 14:12
  • and why should I do getapplicationContext().getApplication() for intent service? – Alex Oct 16 '17 at 14:13
  • Intent service extends service, therefor you don't have a context. When you do `(CustomApplication)getApplication` in an Activity you are basically writing `(CustomApplication)this.getApplication`. Thats why in classes that are not Activities you need to either pass the context, or get the application context, which is the case of an IntentService – Ricardo Oct 16 '17 at 14:16
  • I will, I gotta do a staged rollout on the audience. I'm not capable to reproduce it on any of my devices at any scenario – Alex Oct 16 '17 at 14:18
  • And as I mentioned in my question, I tried both `.getApplicationContext()` and `.getApplication()` from service. And they all failed – Alex Oct 16 '17 at 14:21
  • I just crashes ~50-100 times a day. So there's a specific scenario during which .getApplication/getApplicationContext does not return a CustomApplication instance. I suppose it to be a vendor specific issue – Alex Oct 16 '17 at 14:22
  • It is a possibility. I've worked with a few applications already with thousands of monthly users and never had a problem with the approach I gave you – Ricardo Oct 16 '17 at 14:26
  • But you gave me the same approach I use – Alex Oct 16 '17 at 14:32
  • I have my application class registered in manifest, and I do the same class casting of .getApplication as you do. What's the difference? – Alex Oct 16 '17 at 14:33
  • the only difference I've found out is you do .getApplicationContext().getApplication() and I asked you to provide me with some links to resources to clarify that for me – Alex Oct 16 '17 at 14:33
  • I explained when and why you must call getApplicationContext in a comment above. read it – Ricardo Oct 16 '17 at 14:38
  • But intent Service has context. It is a context. You can examine it both in android SDK and android documentation; And it has both .getApplication() and .getApplicationContext() methods – Alex Oct 16 '17 at 14:42
  • You are correct. I was confusing with BroadcastReceiver, thats where you need to call getApplicationContext. – Ricardo Oct 16 '17 at 14:46