androidmalin / AndroidComponentPlugin

Android上简单实现四大组件的插件化,供学习使用
459 stars 57 forks source link

主题报错 #10

Open liu1352183717 opened 1 year ago

liu1352183717 commented 1 year ago

你好!我在使用你的库集成到我的项目时报错View class com.google.android.material.button.MaterialButton is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant). 这个是什么原因呢,在你的项目中没有报错,我也看了是反射修改了主题,但是我集成后就报这个错误,我的项目是33的版本的,1+8pro手机

androidmalin commented 1 year ago
  1. 克隆代码, 切到 develop_kotlin 分支 git clone git@github.com:androidmalin/AndroidComponentPlugin.git -b develop_kotlin
  2. 运行根目录下的 build_debug_apk.sh脚本, 生成插件demo apk, 拷贝到宿主目录, 安装宿主apk ./build_debug_apk.sh
  3. 安装后看看效果, 能不能正常启动插件.
liu1352183717 commented 1 year ago

很抱歉那么久才回复你,我一直在找原因,我把你的项目clone下来是可以运行的,设置主题也是生效的,但是我把你的项目模块化集成到我的项目中后设置主题好像没有生效,不知道是什么原因,其中StubActivity中的主题是可以生效的,但是继承AppCompatActivity的StubAppCompatActivity的主题好像没有生效 还是报错View class com.google.android.material.button.MaterialButton is an AppCompat widget that can only be used with a Theme.AppCompat theme (or descendant).
和 android.view.InflateException: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Error inflating class com.google.android.material.button.MaterialButton

如果不用com.google.android.material.button.MaterialButton 这个控件也是可以正常运行的

我验证了修改代码主题 ` @Suppress("SameParameterValue") private fun selectSystemTheme(): Int { val targetSdkVersion: Int = Build.VERSION.SDK_INT val theme: Int = when { targetSdkVersion < 24 -> R.style.AppCompatTheme else -> R.style.AppCompatTheme }

    return theme
}`

这里是运行了的

这是什么原因你知道吗

这是详细报错

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.malin.plugin/com.malin.plugin.PluginAppCompatActivity}: android.view.InflateException: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Error inflating class com.google.android.material.button.MaterialButton at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3876) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4018) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:111) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2474) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:240) at android.os.Looper.loop(Looper.java:351) at android.app.ActivityThread.main(ActivityThread.java:8416) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013) Caused by: android.view.InflateException: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Error inflating class com.google.android.material.button.MaterialButton Caused by: android.view.InflateException: Binary XML file line #25 in com.malin.plugin:layout/plugin_activity: Error inflating class com.google.android.material.button.MaterialButton Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at android.view.LayoutInflater.createView(LayoutInflater.java:870) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1022) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:977) at android.view.LayoutInflater.rInflate(LayoutInflater.java:1139) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1100) at android.view.LayoutInflater.inflate(LayoutInflater.java:693) at android.view.LayoutInflater.inflate(LayoutInflater.java:542) at android.view.LayoutInflater.inflate(LayoutInflater.java:489) at com.malin.plugin.PluginAppCompatActivity.onCreate(PluginAppCompatActivity.kt:17) at android.app.Activity.performCreate(Activity.java:8422) at android.app.Activity.performCreate(Activity.java:8395) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1403) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3849) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4018) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:111) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2474) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:240) at android.os.Looper.loop(Looper.java:351) at android.app.ActivityThread.main(ActivityThread.java:8416) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013) Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant). at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:247)

androidmalin commented 1 year ago

你可以仔细看看, 插件apk工程中的代码

插件Activity 需要继承自BaseActivity, 插件中的上下文context需要从插件apk中 获取 Resources 的

https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/pluginapk/src/main/java/com/malin/plugin/PluginAppCompatActivity.kt#L17C33-L17C41

https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/pluginapk/src/main/java/com/malin/plugin/BaseActivity.kt#L21

https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/pluginapk/src/main/java/com/malin/plugin/PluginResourceUtil.kt#L23C47-L23C58

你是在自己的代码中使用的吧? 在公司项目里使用的话, 推荐你 用 腾讯的插件化框架 https://github.com/Tencent/Shadow

liu1352183717 commented 1 year ago

https://github.com/androidmalin/AndroidComponentPlugin/assets/41316730/d5288879-69d4-45c6-8daa-b239b3d8a1dd

liu1352183717 commented 1 year ago

我没有改动你的代码,只是把你的项目作为模块化导入我的项目了,他确实是以插件化运行的, 但是报错在AppCompatActivity这个报错了,我怀疑LayoutInflater.from(mContext).inflate(R.layout.plugin_activity, null) 查找material的控件没有找到 测试普通Button控件是可以正常运行的

androidmalin commented 1 year ago

你需要修改一下插件工程中的代码

https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/pluginapk/src/main/java/com/malin/plugin/BaseActivity.kt#L17C72-L17C72

hostAppClazz = Class.forName("com.malin.hook.MApplication")

把"com.malin.hook.MApplication" 改成你的宿主工程中自定义的Application的全路径名称.

"com.malin.hook.MApplication" 这个类全称来自于demo的宿主工程

代码如下 https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/app/src/main/java/com/malin/hook/MApplication.kt#L9

https://github.com/androidmalin/AndroidComponentPlugin/blob/develop_kotlin/app/src/main/AndroidManifest.xml#L6

liu1352183717 commented 1 year ago

呃,我觉得我还没那种小白到那种程度😥

liu1352183717 commented 1 year ago

我好像找到原因了,就是你的项目中反射设置主题好像没有生效,反射设置的主题是宿主自身的主题,而不是插件的主题,然而在插件中我们又用的是插件中的资源,在你的项目中我反编译看了打包后的源码,可以看出插件和宿主两个的style是一样的资源id,所以我们在宿主中反射设置插件的主题,刚好巧合的对上了插件自生的主题样式id,这样在插件中 LayoutInflater.from(mContext).inflate(R.layout.plugin_activity, null)也不会报错
private fun selectSystemTheme(): Int { val targetSdkVersion: Int = Build.VERSION.SDK_INT val theme: Int = when { targetSdkVersion < 24 -> R.style.Theme_Wumin else ->R.style.Theme_Wumin } return theme } 应该这里的问题

我注释掉设置主题那一段后,还是报错,我不知道主题样式是在什么时机被加载的,后面你插件中的反射设置theme好像也没有生效。。

我也不知都我说的对不对

liu1352183717 commented 1 year ago

找到了问题所在了,还是资源问题,插件中加载了宿主的类,但是资源又是插件自身的,主要还是插件的类和宿主的类的资源id不一样,

androidmalin commented 1 year ago

抱歉, 最近一直很忙, 没有时间看github上你的留言.

找到了问题所在了,还是资源问题,插件中加载了宿主的类,但是资源又是插件自身的,主要还是插件的类和宿主的类的资源id不一样

Demo工程里的代码, 是不是也有这种问题呢? 你可以在你的fork项目里, 改一下, 提交一下代码, 我学习一下.

liu1352183717 commented 1 year ago

我也没有解决😭😭😭

主要是我的项目引入了很多包,as编译后,资源id就对不上了,像你的那个简单的例子的话宿主和插件资源id就是一样的,然后就能正常找到,

liu1352183717 commented 1 year ago

勉强解决问题 目前使用的是通过资源合并方式 好像高版本才行

androidmalin commented 8 months ago

@liu1352183717 刚看到, 你还在研究呀, 好有毅力!