BootstrapApplication无法强制转换为ApplicationClass

时间:2016-04-08 09:20:29

标签: android instant-run

我正在运行Android Studio ver 2.0的新稳定版。当我禁用即时运行时,我的应用程序运行正常,但当我打开它时,它给了我这个错误:

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

CustomApplication是我通过上下文获取的Application类。但我似乎无法得到它。当启用即时运行时,我的类被转换为BootstrapApplication然后失败。

我的应用程序是一个像FB chatheads这样的浮动服务。

我有最新的gradle版本:

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

其他答案在这里说,即时运行尝试进行热交换代码;这会导致应用程序类被移动。

那么我该如何解决这个问题呢?

2 个答案:

答案 0 :(得分:6)

解决方案#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();
    }

   ...

}

答案 1 :(得分:0)

&#13;
&#13;
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;
}
&#13;
&#13;
&#13;

解决方案#2中的

我添加一个案例