描述:

关于自定义控件无法转换的问题:Caused by: java.lang.ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.LoadingView

我相信大家在组件化开发的时候会遇到这样的问题,并且很疑惑,下面我给大家分析下为什么会出现崩溃无法转换的问题。

1.首先创建项目

首先创建一个主项目demoapp:

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

然后再创建demolibrary:

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

2.然后主项目(demoapp)引用(demolibrary)

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

3.创建自定义控件LoadingView

主项目和library里面都创建一个相同名字的自定义控件LoadingView
ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

4.然后在主项目和Library项目对应layout文件下创建一个activity_main.xml文件

主项目xml的内容是这样的:
ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

demolibrary里的xml内容是这样的:
ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

5.写出测试代码

主项目和demolibrary里都在各自的MainActivity里初始化自定义LoadingView控件
LoadingView loadingView = (LoadingView) findViewById(R.id.loading);
然后在主项目里做一个跳转到demolibrary   MainAcitivty的操作


jumptomain.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, com.demolib.MainActivity.class);
        startActivity(intent);
    }
});

6.测试结果

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

7.原因分析

首先我们主项目和library里都有各自的自定义控件LoadingView,然后当我们编译的时候会生成对应的R.id
这个时候发现主项目和library项目的build文件里生成的R.id都是一样的

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

ClassCastException: com.demoapp.dialog.img.LoadingView cannot be cast to com.demolib.dialog.img.Load

大家有没有发现loading的值是一样的(可能是编译器的Bug),并且library里的loading是灰色的并没有被引用到。
所以在调用自定义控件的时候所有引用的R.id.loading的地址都是指向主项目R文件,当在主项目做跳转到library这个时候找不到指定的包名下的类,也无法转换就会报运行时异常。

8.解决方案

1.把自定义控件抽取出来作为公用的
2.可以命名不同的类名字
3.补充一点:如果是两个项目中都有相同名字的xml文件一定要命名成不同的名字才行,否则所有的引用都是引用的主项目的xml(虽然不会报错崩溃)

欢迎吐槽



相关文章: