簡體   English   中英

Android 動態特性模塊,找不到資源

[英]Android dynamic feature module, resource not found

當下載的功能模塊發布到 Play 商店時,我在啟動活動時遇到問題。 它總是在下載的模塊活動中的 setContentView() 上崩潰。

java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx/xxxActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x7e080000
Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7e080000
    at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:227)
    at android.content.res.Resources.loadXmlResourceParser(Resources.java:2149)
    at android.content.res.Resources.getLayout(Resources.java:1158)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:421)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
    at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
    at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)

真正奇怪的是,如果我發布一個新版本的應用程序(唯一的變化是版本代碼)來播放商店並更新應用程序,一切都會完美無缺。

當我卸載應用程序並再次安裝時,崩潰返回。

我的應用程序繼承了 SplitCompatApplication() 並且只是為了確保我已經嘗試添加:

override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase)
        SplitCompat.install(this)
    }

到功能模塊中的活動並禁用proguard以確保在縮小期間沒有刪除任何內容

我的 SplitInstallStateUpdatedListener

private val listener = SplitInstallStateUpdatedListener { state ->
        val multiInstall = state.moduleNames().size > 1
        state.moduleNames().forEach { name ->
            // Handle changes in state.
            when (state.status()) {
                SplitInstallSessionStatus.DOWNLOADING -> {
                    //  In order to see this, the application has to be uploaded to the Play Store.
                    displayLoadingState(state, "Laddar ner $name")
                }
                SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> {
                    /*
                      This may occur when attempting to download a sufficiently large module.
                      In order to see this, the application has to be uploaded to the Play Store.
                      Then features can be requested until the confirmation path is triggered.
                     */
                    startIntentSender(state.resolutionIntent()?.intentSender, null, 0, 0, 0)
                }
                SplitInstallSessionStatus.INSTALLED -> {
                    if(toInstall.isNotEmpty() && toInstall.contains(name)) {
                        toInstall.remove(name)
                    }
                    if(toInstall.isEmpty()) {
                        // Updates the app’s context with the code and resources of the
                        // installed module. (should only be for instant apps but tried it anyway, no change)
                        SplitInstallHelper.updateAppInfo(applicationContext) 
                        Handler().post {
                            viewModel.goToOverview()
                        }
                    }
                }

                SplitInstallSessionStatus.INSTALLING -> displayLoadingState(state, "Installerar $name")
                SplitInstallSessionStatus.FAILED -> {
                    toastAndLog("Error: ${state.errorCode()} for module ${state.moduleNames()}")
                }
            }
        }
    }

此代碼根據用戶聲明下載模塊並在基本應用程序中啟動活動

下載的模塊活動然后從 BottomSheetDialogFragment 開始,如下所示:

xxx.setOnClickListener(view -> {
                    Intent intent = new Intent();
                    String packageName = Constants.MODULE_BASEPACKAGE + "." + Constants.MODULE_XXXXX;
                    intent.setClassName(getActivity().getPackageName(),packageName + ".XxxxxActivity" );
                    ParcelUuid parcelUuid = new ParcelUuid(UUID.randomUUID());
                    intent.putExtra("uuid", parcelUuid);
                    startActivity(intent);
                    dismiss();
                });

我完全不知道接下來要嘗試什么。 似乎在安裝更新之前不會更新資源列表並且重新啟動應用程序是不夠的,或者我只是錯過了一些簡單的東西?

您始終可以從動態模塊內的主項目訪問資源,因此您可以將動態模塊的資源放在主應用程序中,然后使用主應用程序中的 R.java。

但是,打開這些資源的正確方法是在動態交付的活動中使用 SplitCompat.install(this)

這似乎是 com.android.tools.build:gradle:3.2.1 中的一個錯誤,當我升級到 3.3.0 時,問題自行解決。

希望它可以幫助遇到此問題的其他人......

我有一個完全相同的問題; 全新安裝因Resources$NotFoundException崩潰,但后續升級工作正常(不會再次下載動態模塊)。 但我的情況略有不同,因為我想通過導航加載一個 Fragment,而不是在動態模塊中啟動一個 Activity。 在這種情況下,我應該直接導航並讓 Navigation 完成它的工作,而無需手動檢查模塊是否已加載(有關更多信息,請參閱https://developer.android.com/guide/navigation/navigation-dynamic )。

// Just navigate without calling splitInstallManager.installedModules.contains()
findNavController().navigate(DynamicDeliveryDirections.actionDynamicFragment())

如果你想啟動一個活動,你需要檢查模塊是否被加載,就像你已經在做的那樣。 我建議您看一下 Google 的示例,它完全符合您的要求。

https://codelabs.developers.google.com/codelabs/on-demand-dynamic-delivery/index.html?index=..%2F..index#1

至於我的情況,我必須確保包名稱是正確的。 例如,如果主模塊的包名稱是com.example.foo並且動態模塊是com.example.foo.dynamic_activity ,那么在動態模塊中啟動 Activity 將如下所示。

Intent().setClassName(
    "com.example.foo",
    "com.example.foo.dynamic_activity.DynamicActivity"
).also {
    startActivity(it)
}

我不知道它為什么有效,但對我來說使用 AppCompatActivity 解決了這個問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM