You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Glance Widget按需动态交付后无法加载崩溃问题咨询

问题描述
  • 应用初始体积2.8MB,集成Glance Widget后飙升至5.3MB,计划采用Dynamic Feature/Delivery实现Widget按需下载,降低初始安装包体积。
  • 遇到异常:Widget模块下载完成后仍无法渲染,启动器显示“Can't load widget”。
  • 对比现象:
    • 设置为安装时交付无错误:
      <dist:install-time>
          <dist:removable dist:value="false"/>
      </dist:install-time>
      
    • 切换为按需交付后问题触发:
      <dist:on-demand />
      
  • 错误日志:
    Error inflating AppWidget AppWidgetProviderInfo(UserHandle{0}/ComponentInfo{com.example.foo/com.example.foo.glance.ui.glance.MyWidgetReceiver})
    android.content.res.Resources$NotFoundException: Resource ID #0x0
        at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:240)
        at android.content.res.Resources.loadXmlResourceParser(Resources.java:2529)
        at android.content.res.Resources.getLayout(Resources.java:1335)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:536)
        at android.appwidget.AppWidgetHostView.getDefaultView(AppWidgetHostView.java:926)
        at android.appwidget.AppWidgetHostView.applyRemoteViews(AppWidgetHostView.java:579)
        at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:533)
        at com.android.launcher3.widget.LauncherAppWidgetHostView.updateAppWidget(LauncherAppWidgetHostView.java:247)
        at android.appwidget.AppWidgetHost.updateAppWidgetView(AppWidgetHost.java:529)
        at android.appwidget.AppWidgetHost$UpdateHandler.handleMessage(AppWidgetHost.java:158)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.app.ActivityThread.main(ActivityThread.java:8751)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
    
解决方案

1. 彻底隔离Widget组件与资源

把Widget的AppWidgetProvider实现类、Glance逻辑代码、布局资源、Drawable资源全量迁移到动态feature模块,主模块不能残留任何与Widget关联的资源或代码引用,避免系统加载时混淆资源路径。

2. 修复动态模块资源访问逻辑

崩溃核心是系统启动器无法找到Widget对应的资源,需做以下调整:

  • 动态模块的appwidget-provider配置xml中,所有资源引用(如android:initialLayout)必须使用模块内的相对路径,确保资源完全由动态模块自身管理。
  • 禁止在主模块中引用动态模块的资源,所有Widget相关资源的访问都限定在动态模块内部。

3. 模块安装完成后主动刷新Widget列表

用户触发Widget下载后,必须等待动态模块完全安装初始化,再通知系统刷新Widget列表,否则系统无法识别新安装的Widget组件:

val splitInstallManager = SplitInstallManagerFactory.create(context)
splitInstallManager.registerListener { sessionState ->
    if (sessionState.status() == SplitInstallSessionStatus.INSTALLED) {
        // 发送广播通知系统更新应用组件信息,包括Widget
        val intent = Intent(Intent.ACTION_PACKAGE_CHANGED).apply {
            setPackage(context.packageName)
            addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND)
        }
        context.sendBroadcast(intent)
    }
}

4. 规范动态模块Manifest配置

确保动态模块的Manifest正确声明交付方式与Widget组件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="com.example.foo.widget">

    <dist:module
        dist:instant="false"
        dist:title="@string/widget_module_title">
        <dist:on-demand />
    </dist:module>

    <!-- 完整声明Widget Receiver -->
    <receiver android:name=".MyWidgetReceiver">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_widget_info" />
    </receiver>
</manifest>

5. 正确测试动态交付流程

  • 不要直接用Android Studio的「Run」按钮测试,必须生成App Bundle,通过Internal App Sharing、Google Play Console或bundletool生成APK集安装测试,本地直接运行无法模拟真实的动态交付环境。
  • 确保测试设备为Android 5.0+,且Google Play服务版本符合动态交付要求。

内容的提问来源于stack exchange,提问作者DTechnlogy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:20:51