Tencent / Shadow

零反射全动态Android插件框架
BSD 3-Clause "New" or "Revised" License
7.46k stars 1.3k forks source link

嵌套 PreferenceFragmentCompat 导致 java.lang.ClassCastException: cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity #1194

Closed LeonWu6 closed 1 year ago

LeonWu6 commented 1 year ago

在插件APP中, 第一个 UI 是继承 PreferenceFragmentCompat 的,然后通过 Intent 拉起第二层UI,第二层UI 也是继承 PreferenceFragmentCompat 的。 当拉起第二层 UI 时,会报如下异常:

AndroidRuntime: Shutting down VM --------- beginning of crash AndroidRuntime: FATAL EXCEPTION: main AndroidRuntime: Process: com.oplus.en:plugin, PID: 29307 AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.oplus.en/com.oplus.en.runtime.PluginDefaultProxyActivity}: java.lang.RuntimeException: java.lang.ClassCastException: com.oplus.en.cellular_app.rf.nvbackupui.NVBackupUI cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3876) AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4018) AndroidRuntime: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:111) AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2474) AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106) AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:240) AndroidRuntime: at android.os.Looper.loop(Looper.java:351) AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8426) AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013) AndroidRuntime: Caused by: java.lang.RuntimeException: java.lang.ClassCastException: com.oplus.en.cellular_app.rf.nvbackupui.NVBackupUI cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity AndroidRuntime: at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:159) AndroidRuntime: at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:84) AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8460) AndroidRuntime: at android.app.Activity.performCreate(Activity.java:8433) AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1403) AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3849) AndroidRuntime: ... 12 more AndroidRuntime: Caused by: java.lang.ClassCastException: com.oplus.en.cellular_app.rf.nvbackupui.NVBackupUI cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity AndroidRuntime: at com.tencent.shadow.core.runtime.ShadowAppComponentFactory.instantiateActivity(ShadowAppComponentFactory.java:18) AndroidRuntime: at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45) AndroidRuntime: at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:120) AndroidRuntime: ... 17 more

是 Shadow 框架无法支持嵌套 PreferenceFragmentCompat 吗?

代码流程:

  1. 继承关系 RfFragment 继承于 EngineerFragmentCompat, EngineerFragmentCompat 继承于 PreferenceFragmentCompat

  2. 调用关系 RfFragment 通过 intent 调用起 NVBackupUI NVBackupUI 也是继承于 PreferenceFragmentCompat

当通过 RfFragment 调起 NVBackupUI 时,异常发生。

下面是代码:

  1. EngineerFragmentCompat.kt (基类,继承于PreferenceFragmentCompat)

    
    package com.oplus.en.cellular_app
    import android.content.Context
    import android.os.Bundle
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import androidx.fragment.app.Fragment
    import androidx.preference.PreferenceFragmentCompat
    import androidx.preference.PreferenceScreen
    import com.tencent.shadow.core.common.Logger
    import com.tencent.shadow.core.common.LoggerFactory

open class EngineerFragmentCompat : PreferenceFragmentCompat() { private val mLogger: Logger = LoggerFactory.getLogger(EngineerFragmentCompat::class.java) private var mContext: Context? = null

override fun onAttach(p0: Context) {
    super.onAttach(p0)
    mContext = p0
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val preferenceScreen: PreferenceScreen = preferenceManager.preferenceScreen
    for (i in 0 until preferenceScreen.preferenceCount) {
        val preference = preferenceScreen.getPreference(i)
        val intent = preference.intent
        if (intent != null) {
            preference.isEnabled = true
        } else {
            mLogger.warn("onViewCreated preference is not available for i: $i")
            preference.isEnabled = false
        }
    }
}
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View {
    val view: View = super.onCreateView(inflater, container, savedInstanceState)
    view.setBackgroundColor(
        resources.getColor(R.color.material_grey_850, mContext?.theme)
    )
    return view
}
override fun getCallbackFragment(): Fragment {
    return this
}

}

---------------------------------------------------------------
2. RfFragment.kt  (第一层 PreferenceFragmentCompat UI)
----------------------------------------------------------------

package com.oplus.en.cellular_app import android.os.Bundle class RfFragment : EngineerFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.fragment_rf_container) } }

---------------------------------------------------------------
3. fragment_rf_container.xml (第一层嵌套 PreferenceFragmentCompat UI 的 资源文件)
---------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="rf_container" android:title="@string/rf_items"> <androidx.preference.Preference android:key="nv_backup" android:title="@string/nv_backup_title"> <intent android:action="android.intent.action.MAIN" android:targetClass="com.oplus.en.cellular_app.rf.nvbackupui.NVBackupUI" android:targetPackage="com.oplus.en" /> </androidx.preference.Preference>

--------------------------------------------------------------
4. NVBackupUI.kt (第二层 PreferenceFragmentCompat UI)
--------------------------------------------------------------

package com.oplus.en.cellular_app.rf.nvbackupui import android.os.Bundle import androidx.preference.PreferenceFragmentCompat import com.oplus.en.cellular_app.R

class NVBackupUI : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.qti_nv_options) } }

--------------------------------------------------------------
5.  qti_nv_options.xml (第二层嵌套 PreferenceFragmentCompat UI 的 资源文件)
--------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>

shifujun commented 1 year ago

大致浏览之后,我是比较相信这里是遇到bug了的。因为PreferenceFragmentCompat应该只是个androidx的fragment,怎么都不应该被实例化成Activity(ShadowActivity)的。所以问题可能出在ShadowAppComponentFactory上。

androidx不需要特别支持,所以我们应该找出它依赖的系统api有什么需要支持的。

如果你不能自己解决这个问题,最好fork项目后在sample或test工程里用最少代码复现一下这个问题。

androidx相关的例子可以在这个插件工程里添加代码: https://github.com/Tencent/Shadow/tree/master/projects/test/plugin/androidx-cases/test-plugin-androidx-cases

LeonWu6 commented 1 year ago

Hi @shifujun 由于我们公司网络限制,无法 push code changes 到 github 上,请辛苦浏览复制以下复现问题的测试代码。 我在 Sample 里面加了一个 testcase,可复现此 Issue 所说的问题。 请看下面的 patch

  1. git patch, (打补丁) 1.1 请在您的 PC上创建 Issue#1194_Change.patch 文件,在 NotePad++ 打开 Issue#1194_Change.patch; 1.2 请将此 patch 内容复制到您的 Issue#1194_Change.patch 文件中,将 Issue#1194_Change.patch 文件拷贝到 Shadow 仓库的根目录; 1.3 在 Shadow 仓库中使用 git apply Issue#1194_Change.patch 打入补丁。

以下是补丁的内容:(请使用补丁内容)

diff --git a/projects/sample/source/sample-plugin/sample-app/build.gradle b/projects/sample/source/sample-plugin/sample-app/build.gradle
index 5bb93f01..85546e31 100644
--- a/projects/sample/source/sample-plugin/sample-app/build.gradle
+++ b/projects/sample/source/sample-plugin/sample-app/build.gradle
@@ -18,6 +18,7 @@ buildscript {

 apply plugin: 'com.android.application'
 apply plugin: 'com.tencent.shadow.plugin'
+apply plugin: 'kotlin-android'

 android {
     compileSdkVersion project.COMPILE_SDK_VERSION
@@ -68,6 +69,7 @@ dependencies {
     //Shadow Transform后业务代码会有一部分实际引用runtime中的类
     //如果不以compileOnly方式依赖,会导致其他Transform或者Proguard找不到这些类
     pluginCompileOnly 'com.tencent.shadow.core:runtime'
+    implementation 'androidx.preference:preference:1.2.0'
 }

 preBuild.dependsOn(":sample-host-lib:jarDebugPackage")
diff --git a/projects/sample/source/sample-plugin/sample-app/src/main/AndroidManifest.xml b/projects/sample/source/sample-plugin/sample-app/src/main/AndroidManifest.xml
index abac57e8..83fbc3c7 100644
--- a/projects/sample/source/sample-plugin/sample-app/src/main/AndroidManifest.xml
+++ b/projects/sample/source/sample-plugin/sample-app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     package="com.tencent.shadow.sample.plugin.app.lib">

     <uses-feature android:glEsVersion="0x00020000" />
@@ -62,6 +63,8 @@
         <activity android:name=".usecases.host_communication.PluginUseHostClassActivity" />
         <activity android:name=".usecases.webview.WebViewActivity" />
         <activity android:name=".usecases.fragment.TestDialogFragmentActivity" />
+        <activity android:name=".usecases.preferencefragmentcompatcase.RfFragment"
+            tools:ignore="Instantiatable" />

         <provider
             android:authorities="${applicationId}.provider.test"
diff --git a/projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/UseCaseApplication.java b/projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/UseCaseApplication.java
index 93c05284..3f43f005 100644
--- a/projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/UseCaseApplication.java
+++ b/projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/UseCaseApplication.java
@@ -22,6 +22,7 @@ import com.tencent.shadow.sample.plugin.app.lib.usecases.fragment.TestDynamicFra
 import com.tencent.shadow.sample.plugin.app.lib.usecases.fragment.TestXmlFragmentActivity;
 import com.tencent.shadow.sample.plugin.app.lib.usecases.host_communication.PluginUseHostClassActivity;
 import com.tencent.shadow.sample.plugin.app.lib.usecases.packagemanager.TestPackageManagerActivity;
+import com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase.RfFragment;
 import com.tencent.shadow.sample.plugin.app.lib.usecases.provider.TestDBContentProviderActivity;
 import com.tencent.shadow.sample.plugin.app.lib.usecases.provider.TestFileProviderActivity;
 import com.tencent.shadow.sample.plugin.app.lib.usecases.receiver.TestDynamicReceiverActivity;
@@ -51,7 +52,8 @@ public class UseCaseApplication extends Application {
                 new TestActivityWindowSoftMode.Case(),
                 new TestActivitySetTheme.Case(),
                 new TestActivityOptionMenu.Case(),
-                new WebViewActivity.Case()
+                new WebViewActivity.Case(),
+                new RfFragment.Case()
         });
         useCases.add(activityCategory);

@@ -97,5 +99,8 @@ public class UseCaseApplication extends Application {
                 new PluginUseHostClassActivity.Case(),
         });
         useCases.add(communicationCategory);
+        UseCaseCategory PreferenceFragmentCompatCategory = new UseCaseCategory("PreferenceFragmentCompat嵌套用例",
+                new UseCase[]{new RfFragment.Case(),});
+        useCases.add(PreferenceFragmentCompatCategory);
     }
 }
diff --git a/projects/sample/source/sample-plugin/sample-app/src/main/res/values/strings.xml b/projects/sample/source/sample-plugin/sample-app/src/main/res/values/strings.xml
index 8cb0af94..289eb0cb 100644
--- a/projects/sample/source/sample-plugin/sample-app/src/main/res/values/strings.xml
+++ b/projects/sample/source/sample-plugin/sample-app/src/main/res/values/strings.xml
@@ -20,5 +20,9 @@
     <!-- Simple strings. -->
     <string name="app_name">Shadow主测试用例集合</string>
     <string name="host_add_plugin_view">这是插件中的string资源</string>
+    <string name="nv_backup_title">NV Backup</string>
+    <string name="rf_items">RF Module</string>
+    <string name="qti_nv">NV parameters</string>
+    <string name="qti_adjust">Calibration status</string>
 </resources>

  1. 在 projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/usecases 目录下新增一个 testcase,嵌套调用 PreferenceFragmentCompat

    
    $ git status
    On branch master
    Your branch is up to date with 'origin/master'.

Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore ..." to discard changes in working directory) modified: projects/sample/source/sample-plugin/sample-app/build.gradle modified: projects/sample/source/sample-plugin/sample-app/src/main/AndroidManifest.xml modified: projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/UseCaseApplication.java modified: projects/sample/source/sample-plugin/sample-app/src/main/res/values/strings.xml

Untracked files: (use "git add ..." to include in what will be committed) projects/sample/source/sample-plugin/sample-app/src/main/java/com/tencent/shadow/sample/plugin/app/lib/usecases/preferencefragmentcompatcase/ projects/sample/source/sample-plugin/sample-app/src/main/res/xml/

------------------------------------------------------------------------------------------------------

2.1  com/tencent/shadow/sample/plugin/app/lib/usecases/preferencefragmentcompatcase/RfFragment.kt

package com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase

import android.os.Bundle import com.tencent.shadow.sample.plugin.app.lib.R import com.tencent.shadow.sample.plugin.app.lib.gallery.cases.entity.UseCase

class RfFragment : EngineerFragmentCompat() {

class Case : UseCase() {
    override fun getName(): String {
        return "PreferenceFragmentCompat 嵌套测试"
    }

    override fun getSummary(): String {
        return "测试PreferenceFragmentCompat嵌套"
    }

    override fun getPageClass(): Class<*> {
        return RfFragment::class.java
    }
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    addPreferencesFromResource(R.xml.fragment_rf_container)
}

}

2.2 com/tencent/shadow/sample/plugin/app/lib/usecases/preferencefragmentcompatcase/NVBackupUI.kt

package com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase import android.os.Bundle import android.util.Log import androidx.preference.PreferenceFragmentCompat import com.tencent.shadow.sample.plugin.app.lib.R

class NVBackupUI : PreferenceFragmentCompat() {

private val TAG = "NVBackupUI"
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    Log.d(TAG, "onCreatePreferences")
    addPreferencesFromResource(R.xml.qti_nv_options)
}

}

2.3 com/tencent/shadow/sample/plugin/app/lib/usecases/preferencefragmentcompatcase/EngineerFragmentCompat.kt

package com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase

import android.content.Context import android.os.Build import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceScreen import android.util.Log import androidx.annotation.RequiresApi import com.tencent.shadow.sample.plugin.app.lib.R

open class EngineerFragmentCompat : PreferenceFragmentCompat() {

private val TAG = "EngineerFragmentCompat"
private var mContext: Context? = null

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    Log.d(TAG, "onCreatePreferences")
}

override fun onAttach(p0: Context) {
    super.onAttach(p0)
    mContext = p0
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val preferenceScreen: PreferenceScreen = preferenceManager.preferenceScreen
    for (i in 0 until preferenceScreen.preferenceCount) {
        val preference = preferenceScreen.getPreference(i)
        val intent = preference.intent
        if (intent != null) {
            preference.isEnabled = true
        } else {
            Log.w(TAG, "onViewCreated preference is not available for i: $i")
            preference.isEnabled = false
        }
    }
}

/**
 * 实例化 Fragment 来显示视图,这将在 onCreate 和 onViewCreated 之间调用。
 * */
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    val view: View = super.onCreateView(inflater, container, savedInstanceState)
    view.setBackgroundColor(
        resources.getColor(R.color.material_grey_850, mContext?.theme)
    )
    return view
}

override fun getCallbackFragment(): Fragment {
    return this
}

}

2.4 xml/fragment_rf_container.xml

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="rf_container" android:title="@string/rf_items">

<androidx.preference.Preference
    android:key="nv_backup"
    android:title="@string/nv_backup_title">
    <intent
        android:action="android.intent.action.MAIN"
        android:targetClass="com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase.NVBackupUI"
        android:targetPackage="com.tencent.shadow.sample.host" />
</androidx.preference.Preference>

2.5 xml/qti_nv_options.xml

<?xml version="1.0" encoding="utf-8"?>



3. 测试方法:
基于本代码 commit chagnes
安装 sample-host:installDebug
进入 Shadow Dynamic测试宿主App
点击 启动插件
左边栏选择最后一项:PreferenceFragmentCompat嵌套用例,点击“启动”

4. 异常出现:
插件APP 闪退,UI界面回到宿主UI,com.tencent.shadow.sample.host:plugin Crashed
AndroidRuntime: Shutting down VM
--------- beginning of crash
AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.tencent.shadow.sample.host:plugin, PID: 27763
AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tencent.shadow.sample.host/com.tencent.shadow.sample.plugin.runtime.PluginDefaultProxyActivity}: java.lang.RuntimeException: java.lang.ClassCastException: com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase.RfFragment cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity
AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3876)
AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4018)
AndroidRuntime:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:111)
AndroidRuntime:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
AndroidRuntime:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2474)
AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:106)
AndroidRuntime:     at android.os.Looper.loopOnce(Looper.java:240)
AndroidRuntime:     at android.os.Looper.loop(Looper.java:351)
AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:8426)
AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
AndroidRuntime: Caused by: java.lang.RuntimeException: java.lang.ClassCastException: com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase.RfFragment cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity
AndroidRuntime:     at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:159)
AndroidRuntime:     at com.tencent.shadow.core.runtime.container.PluginContainerActivity.onCreate(PluginContainerActivity.java:84)
AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:8460)
AndroidRuntime:     at android.app.Activity.performCreate(Activity.java:8433)
AndroidRuntime:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1403)
AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3849)
AndroidRuntime:     ... 12 more
AndroidRuntime: Caused by: java.lang.ClassCastException: com.tencent.shadow.sample.plugin.app.lib.usecases.preferencefragmentcompatcase.RfFragment cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity
AndroidRuntime:     at com.tencent.shadow.core.runtime.ShadowAppComponentFactory.instantiateActivity(ShadowAppComponentFactory.java:18)
AndroidRuntime:     at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
AndroidRuntime:     at com.tencent.shadow.core.loader.delegates.ShadowActivityDelegate.onCreate(ShadowActivityDelegate.kt:120)
AndroidRuntime:     ... 17 more
shifujun commented 1 year ago

你前面这个patch我复制下来倒是能像你说的那样复现一个RfFragment cannot be cast to com.tencent.shadow.core.runtime.ShadowActivity的crash。但这个看起来是非常正常的,因为你写了:

override fun getPageClass(): Class<*> {
            return RfFragment::class.java
        }

这是把一个车fragment填到intent里去startActivity了。(https://github.com/Tencent/Shadow/blob/f5800f3a7ff3ddf1edae1b5d78bfc8079ce2f6ae/projects/sample/source/sample-plugin/sample-base-lib/src/main/java/com/tencent/shadow/sample/plugin/app/lib/gallery/cases/UseCaseSummaryFragment.java#L65

如果这就是你说的原本的问题,那肯定是你的业务代码哪写错了,把fragment当activity去start了。

另外你代码中也没有NVBackupUIActivity,看起来莫名其妙的。

特意指明让你在test-plugin-androidx-cases中复现问题就是避免sample-app中依赖的support包和你要添加的androidx冲突。否则你这个例子现在sample-app能单独运行吗?我这很正常的报Duplicate class found了。如果你能运行,我估计也会很正常的报类错误吧。改在test-plugin-androidx-cases中试试吧。test-plugin-androidx-cases和sample-app一样,test-dynamic-host和sample-host一样,只是这些test工程有自动化测试。

另外这样贴代码绝对不是正常的交流方式,你只是赶上我有空贴一下patch而已。你下次还是push上来吧。最不济也可以push到国内的其他公开git仓库上。

LeonWu6 commented 1 year ago

把fragment当activity去start了。

Hi @shifujun 确实,我是把 fragment 当作 activity 去start 了,导致了原来的问题。 感谢您的指导!

另外,回答您的 comment 中的问题:

  1. 另外你代码中也没有NVBackupUIActivity,看起来莫名其妙的。 因为我贴代码时,认为只要调用到第二层嵌套的 PreferenceFragmentCompat UI 即可,不会再进到 NVBackupUIActivity,所以我没有把 NVBackupUIActivity 的代码贴出来。

谢谢!