小部件导致 DeadObjectException - 小包裹上的交易失败

Posted

技术标签:

【中文标题】小部件导致 DeadObjectException - 小包裹上的交易失败【英文标题】:Widgets lead to DeadObjectException - Transaction failed on small parcel 【发布时间】:2017-09-19 11:36:25 【问题描述】:

只要我想显示一个小部件并开始收听,我就会收到以下异常:

// the relevant stack trace, the rest is comming from my code 
// before the code line I posted below
java.lang.RuntimeException: system server dead?
    at android.appwidget.AppWidgetHost.startListening(AppWidgetHost.java:189)
    at com.my.app.utils.WidgetUtil.a(SourceFile:231)
    ...
    android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
    at android.os.BinderProxy.transactNative(Native Method)
    at android.os.BinderProxy.transact(Binder.java:503)
    at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.startListening(IAppWidgetService.java:481)
    at android.appwidget.AppWidgetHost.startListening(AppWidgetHost.java:185)
    at com.my.app.utils.WidgetUtil.a(SourceFile:231)
    ...

我的代码中的源代码如下:

 mAppWidgetManager = AppWidgetManager.getInstance(context);
 mAppWidgetHost = new AppWidgetHost(context, R.string.app_name);
 mAppWidgetHost.startListening(); // <= this line leads to the crash

观察

我的应用在很多手机上都能正常运行(实际上只有一部除外) 上述崩溃仅发生在一台用户设备上(SM-N910C(Samsung Note 4),Android 6.0.1) 用户说,这些小部件在他的启动器中运行良好

有人知道是什么原因造成的吗?这是我可以在我的应用程序中解决的问题吗?用户说小部件在他的启动器中运行良好...

【问题讨论】:

【参考方案1】:

所以,通过简单的 Google 搜索,我找到了 DeadObjectException 的定义:-

你调用的对象已经死掉了,因为它的宿主进程已经不存在了。

据此,很明显您收到此错误是因为托管mAppWidgetHost 的进程已被终止。

现在的问题是您为什么会收到此错误。覆盖和记录onDestroy() 来监控它可能很有用,而且绝对值得一试。但是,由于它可以在除一台设备之外的所有设备上运行,因此onDestroy() 方法很可能没有任何问题。相反,操作系统会在您访问对象之前终止进程。

那么,为什么操作系统要这样做呢?这个问题让我纠结了很久。尽管有大量与该问题相关的谷歌搜索,但我仍然没有明确的答案或解决方案。但是,在花了相当多的时间搜索之后,我注意到了一个特殊性——这个例外的大多数问题,例如this、this 和你的问题都发生在三星设备上。

我的猜测是三星的底层架构导致了这个问题。而且,虽然我不知道为什么会发生这种情况,也没有合理的解决方案,即使经过大量搜索,这仍然是寻找针对三星设备的工作的开始。

更新

我搜索了一下,发现this 的答案。看看问题作者对该问题的最后评论:-

最后通过清单文件中的一行代码就可以正常工作了,这里是android:hardwareAccelerated="false" 如果有人遇到以下错误,请尝试添加上面的行信号11(SIGSEGV),代码1(SEGV_MAPERR)

我不知道这背后的逻辑,也不知道它是否可行。只是分享它,希望它能帮助你——即使是最细微的形式。

【讨论】:

再一次,我该怎么做?小部件由其他应用程序提供,我的应用程序所做的一切都在我的代码示例中,我只告诉另一个应用程序“我显示带有 ID 的小部件,因此请在需要更新此小部件时通知我”并且此注册立即在指定设备上崩溃... 附加信息:我知道它在三星 s6、s7 和 s8 上工作,所以它可能是 note 4 的某些设备特定问题,但我还不知道它为什么会在我的应用程序中崩溃但不在默认启动器中... 您是否尝试过似乎对其他人有用的 hardwareaccelerated = false 方法?【参考方案2】:
DeadObjectException :

你调用的对象已经死掉了,因为它的宿主进程已经不存在了。

可能的解决方案:

1) 覆盖服务的onDestroy() 方法并观察导致它的事件流。如果你没有通过这个方法就捕获了DeadObjectException,那么你的服务应该已经被操作系统杀死了。

2) 通过删除 Typeface ,这可能是因为我在 assets 文件夹中使用的 ttf 请尝试评论字体并测试它希望它确实可以工作

3) 将所有代码放入onCreate。从那里你会看到像NullPointerException 这样的罪魁祸首,但你的代码已经可以顺利运行了。

【讨论】:

您知道小部件是由其他应用程序实现的,我只是告诉另一个应用程序“我显示带有 ID 的小部件,因此请在需要更新此小部件时通知我”。那么应该如何拦截其他app的代码呢?

以上是关于小部件导致 DeadObjectException - 小包裹上的交易失败的主要内容,如果未能解决你的问题,请参考以下文章

Qt半透明背景导致子小部件在父小部件中“印记”

定位的小部件导致孩子消失/异常

Delphi 2007 - ManualFloat 导致小部件控件浮动在所有其他窗口之上

Flutter - 堆栈中定位的小部件导致异常

MaxHeight 导致小部件展开

将小部件添加到滚动区域会导致它们堆叠在一起