BootstrapApplication 无法转换为 ApplicationClass
BootstrapApplication cannot be cast to ApplicationClass
我正在 运行发布 Android Studio 2.0 版的新稳定版本。当我禁用即时 运行 我的应用程序 运行 很好,但是当我打开它时它给我这个错误:
Caused by: java.lang.ClassCastException: com.android.tools.fd.runtime.BootstrapApplication cannot be cast to com.my.app.CustomApplication
CustomApplication 是我通过上下文获得的应用程序 class。但我似乎无法得到它。当即时 运行 开启时,我的 class 被转换为 BootstrapApplication 然后失败。
我的应用是像 FB 聊天头一样的浮动服务。
我有最新的 gradle 版本:
classpath 'com.android.tools.build:gradle:2.0.0'
这里的其他答案说即时 运行 尝试进行代码热插拔;这会导致应用程序 class 被移动。
那么我该如何解决这个问题?
解决方案#1
- 在设置
中禁用 Instant run
解决方案#2
- 使用反射从 BootstrapApplication 获取真正的应用程序
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;
}
在某处使用:
Context applicationContext = getContext().getApplicationContext();
CustomApplication application = getRealApplication(applicationContext);
使用示例:
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();
}
...
}
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;
}
在解决方案 #2 中
我加一个案例
我正在 运行发布 Android Studio 2.0 版的新稳定版本。当我禁用即时 运行 我的应用程序 运行 很好,但是当我打开它时它给我这个错误:
Caused by: java.lang.ClassCastException: com.android.tools.fd.runtime.BootstrapApplication cannot be cast to com.my.app.CustomApplication
CustomApplication 是我通过上下文获得的应用程序 class。但我似乎无法得到它。当即时 运行 开启时,我的 class 被转换为 BootstrapApplication 然后失败。
我的应用是像 FB 聊天头一样的浮动服务。
我有最新的 gradle 版本:
classpath 'com.android.tools.build:gradle:2.0.0'
这里的其他答案说即时 运行 尝试进行代码热插拔;这会导致应用程序 class 被移动。
那么我该如何解决这个问题?
解决方案#1 - 在设置
中禁用 Instant run解决方案#2 - 使用反射从 BootstrapApplication 获取真正的应用程序
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;
}
在某处使用:
Context applicationContext = getContext().getApplicationContext();
CustomApplication application = getRealApplication(applicationContext);
使用示例:
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();
}
...
}
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;
}
在解决方案 #2 中 我加一个案例