问题
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?
回答1:
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();
}
...
}
回答2:
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
来源:https://stackoverflow.com/questions/36495954/bootstrapapplication-cannot-be-cast-to-applicationclass