BootstrapApplication cannot be cast to ApplicationClass
Asked Answered
P

2

2

I'm running the new stable release of Android Studio ver 2.0. When I disable instant run my app runs fine, but when I turn it on it gives me this error:

Caused by: java.lang.ClassCastException: com.android.tools.fd.runtime.BootstrapApplication cannot be cast to com.my.app.CustomApplication

CustomApplication is an Application class that I get through a context. But I can't seem to get it. When instant run is on, my class is cast as BootstrapApplication then fails.

My app is a floating service like FB chatheads.

I have the latest gradle build:

classpath 'com.android.tools.build:gradle:2.0.0'

Other answers here say that instant Run tries to do hot swapping of code; this causes the application class to be moved.

So how can I get around this?

Pavia answered 8/4, 2016 at 9:20 Comment(6)
You're trying to get current running app? Or You're trying to get your own app like getApplication()?Mascarenas
@AntonShkurenko getting my own app line getApplication(). The solution I selected below worked for me :)Pavia
Please check this and this answerVeritable
@AmitVaghela All your links just say to turn off instant run.Pavia
try doing that, it may solve your issue.Veritable
@AmitVaghela Did you not read the answers here? It's already solved.Pavia
P
6

Solution #1 - Disable Instant run in Settings

Solution #2 - Get real application from BootstrapApplication using reflection

public static CustomApplication getRealApplication (Context applicationContext)
{
    CustomApplication application = null;

    if (applicationContext instanceof CustomApplication)
    {
        application = (CustomApplication) applicationContext;
    }
    else
    {
        Application realApplication = null;
        Field magicField = null;
        try
        {
            magicField = applicationContext.getClass().getDeclaredField("realApplication");
            magicField.setAccessible(true);
            realApplication = (Application) magicField.get(applicationContext);
        }
        catch (NoSuchFieldException e)
        {
            Log.e(TAG, e.getMessage());
        }
        catch (IllegalAccessException e)
        {
            Log.e(TAG, e.getMessage());
        }

        application = (CustomApplication) realApplication;
    }

    return application;
}

Using somewhere:

    Context applicationContext = getContext().getApplicationContext();
    CustomApplication application = getRealApplication(applicationContext);

Example of use:

public class MyProvider extends OrmLiteProvider<OrmLiteSqliteOpenHelper, OrmLiteUriMatcher<OrmLiteMatcherEntry>>
{
    @Override
    protected OrmLiteSqliteOpenHelper createHelper ()
    {
        Context applicationContext = getContext().getApplicationContext();
        CustomApplication application = CustomApplication.getRealApplication(applicationContext);
        return application.getComponent().databaseHelper();
    }

   ...

}
Pisces answered 12/4, 2016 at 14:18 Comment(2)
The first solution did not worked for me. And I don't know how to use the second solution. Please explain it a little bit. I don't know where to write these codes. Thank youKentigera
See above. I add example for using with MyProvider.Pisces
M
0

public static CustomApplication getRealApplication (Context applicationContext)
{
    CustomApplication application = null;

    if (applicationContext instanceof CustomApplication)
    {
        application = (CustomApplication) applicationContext;
    } else if (applicationContext.getApplicationContext() instanceof CustomApplication) {
        application = (CustomApplication) applicationContext.getApplicationContext() ;
    }
    else
    {
        Application realApplication = null;
        Field magicField = null;
        try
        {
            magicField = applicationContext.getClass().getDeclaredField("realApplication");
            magicField.setAccessible(true);
            realApplication = (Application) magicField.get(applicationContext);
        }
        catch (NoSuchFieldException e)
        {
            Log.e(TAG, e.getMessage());
        }
        catch (IllegalAccessException e)
        {
            Log.e(TAG, e.getMessage());
        }

        application = (CustomApplication) realApplication;
    }

    return application;
}

in the solution #2 i add one case

Maragaret answered 11/8, 2017 at 3:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.