- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的小部件由 2 个按钮和一个显示数据的 ListView 组成。大多数情况下,当小部件提供程序的 onUpdate 方法被调用时,一切都会正常加载并且大家都很高兴。
但是我注意到有时在调用更新方法后,小部件完全无法加载其数据。 ListView 是空的,所有按钮都没有响应。就好像我将布局初始化到小部件中,但未设置任何待定 Intent 或列表适配器。
我记录了一切,发现情况并非如此。每次都会创建挂起的 Intent ,就像列表适配器一样,包括失败时的随机时间。很长一段时间我认为它与列表数据如何填充到适配器有关,但看到它每次都有效,再加上按钮 Intent 不起作用的事实让我相信方法 updateAppWidget (ComponentName, RemoteViews) 是失败的原因。但是,没有错误堆栈可以帮助我确认这一点。
这是在 AppWidgetProvider 的 onUpdate 方法调用的单独服务中运行的代码:
@SuppressWarnings("deprecation")
private void updateWidget(int[] ids) {
AppWidgetManager widgetManager = AppWidgetManager.getInstance(this);
int[] widgetIds = widgetManager.getAppWidgetIds(new ComponentName(this, WidgetReceiver.class));
for (int currentWidgetId : widgetIds) {
RemoteViews widget = new RemoteViews(this.getPackageName(), R.layout.widget_layout);
Intent intent = new Intent(this, WidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, currentWidgetId);
intent.putExtra("random", randomNumber);
randomNumber++;
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
widget.setRemoteAdapter(currentWidgetId, android.R.id.list, intent);
Intent clickIntent = new Intent(this, DetailsActivity.class);
PendingIntent pending = PendingIntent.getActivity(this, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
widget.setPendingIntentTemplate(android.R.id.list, pending);
Intent settingsIntent = new Intent(this, WidgetSettingsActivity.class);
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent settingsPending = PendingIntent.getActivity(this, 0, settingsIntent, PendingIntent.FLAG_UPDATE_CURRENT);
widget.setOnClickPendingIntent(R.id.widget_settings, settingsPending);
Intent mainIntent = new Intent(this, MainActivity.class);
PendingIntent mainPending = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
widget.setOnClickPendingIntent(R.id.widget_logo, mainPending);
ComponentName widgetCompName = new ComponentName(this, WidgetReceiver.class);
widgetManager.updateAppWidget(widgetCompName, widget);
}
}
这个错误最令人沮丧的是我无法可靠地重新创建它。有时我会(不幸)走运,它会显示出丑陋的头部,而其他时候(大部分时间)它会完美运行。
我认为有趣的另一件事是,我在 Facebook 的小部件中看到了完全相同的问题。由于保密协议(protocol),当我的应用程序失败时,我无法显示它的屏幕,但我可以显示 Facebook 的相同问题的屏幕:
当 Facebook 的小部件看起来像这样时,它的问题与我的完全相同。未加载数据,所有按钮均无响应。
对于 Facebook 和我的小部件,随后的更新间隔通常会使问题消失。
尽管我很感激我不是唯一遇到此问题的人,但在解决此问题之前我仍然不想发布。这里有没有人遇到过这个,更好的是找到了解决方案,甚至是问题的原因?感谢您的帮助。
编辑:一些有趣的东西。我进行了一项实验,将更新间隔设置为一整天而不是每 30 分钟一次。我的假设是更新方法可能不是原因,是其他原因导致小部件变为空白且无响应。
果然,大约 2 小时后,我检查了我的手机,尽管没有调用更新方法,但小部件已经死了。这会让我相信是其他原因导致了这个问题,而不是像我之前认为的那样 widgetManager.updateAppWidget(widgetCompName, widget);
。
我知道配置更改会导致小部件重新构建,因此它可能会失败。但是,如果需要,我已经使用服务类的 onConfigurationChanged 方法重新加载小部件。是否还有其他情况,例如配置更改会导致小部件自行销毁并重新创建?
最佳答案
经过大量的血汗和泪水,我找到了解决方案。我将推迟几天确认此答案,以确保错误不会再次出现,但经过大量观察后,我认为它已解决。
所以我在原始问题中编辑的评论是正确的。导致问题的不是 AppWidgetManager 的更新方法,而是导致应用小部件重新创建自身的其他一些 Android 进程。不幸的是,我无法隔离该触发器,但我确实找到了解决方案。
在我的 RemoteViewsFactory 类(基本上是用于加载数据集的包装器)中,我有一段代码如下所示:
RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.widget_layout);
if(mItems.size() == 0)
views.setViewVisibility(R.id.widget_empty, View.VISIBLE);
else
views.setViewVisibility(R.id.widget_empty, View.GONE);
AppWidgetManager manager = AppWidgetManager.getInstance(mContext);
ComponentName widgetCompName = new ComponentName(mContext, WidgetReceiver.class);
manager.updateAppWidget(widgetCompName, views);
基本上,如果列表是空的,我会显示一条加载消息,它占据了 ListView 所在的整个区域。如果列表不为空,我会隐藏该消息。
所以这就是正在发生的事情:当工厂被销毁时(可能是出于内存目的),小部件本身 没有。因此,所有设置数据和内容 Intent 的代码都没有运行。然而,工厂被重新创建,它运行了用新的远程 View 对象更新应用程序小部件的代码块。这个远程 View 对象没有执行您在我最初发布的我的 onUpdate() 方法中看到的任何方法,因此它的所有功能都不起作用。
故事的寓意:不要在 RemoteViewsFactory 类中使用 updateAppWidget
!现在,如果您运行所有必要的行,它可能会起作用,但我无法确认这一点。
关于Android AppWidgetManager 方法 updateAppWidget 无法设置 Intent 、加载数据。它是随机发生的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13367397/
以下是更新appwidget的静态方法: public static void updateAppWidget(Context context, int id, WALL_POST_DETAI
我的 Android 应用程序 出现严重问题: 打电话 AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context
谁能告诉我我的广播接收器有什么问题,因为它对时间的变化没有反应?当我显示 Toast 消息时,它确实调用了 updateAppWidget 方法,但时钟小部件没有更新时间。 我已经尝试了来自 stac
我有一个应该显示信息列表的小部件。然而,在研究了大量教程和文档之后,我无法弄清楚为什么它没有显示列表。它将始终显示空 View 。 WidgetService.java 类从未被调用过。 我的代码可以
我有一个运行良好的基于 ListView 的小部件,它依赖于 JSON 网络服务调用来填充自身。我有一个刷新按钮,效果很好,并强制从网络重新加载。我通过使用自定义广播来做到这一点,然后依次调用 o
之前已经讨论过这个问题,但解决方案似乎不适用于我的问题。 我创建了一个 Android 小部件。我正在使用 android 2.0。 当接收到某个 Intent 并且几乎一切正常时,Widget 应该
我正在开发一个应用小部件,它使用 RemoteViews 来显示一个 ListView。为了简单起见,我将对 appwidget 的功能进行类比: 用户将选择将应用程序小部件添加到主屏幕。选择小部件后
所以我有一个应用程序小部件,它可以很好地刷新,像发条一样定期将新位图加载到 ImageView 中。然后,在某个时候,它会静静地停止更新。我可以从日志和我的代码正在查询的服务器上的 Activity
我已经使用向导创建了一个小部件。然后我自定义了布局。我尝试运行,但我得到的只是小部件的错误 View “问题加载小部件”。 查看日志我发现了这个错误: W/AppWidgetHostView: upd
我从小部件用户那里收到有关 android.os.TransactionTooLargeException 的报告: android.os.TransactionTooLargeException a
我的小部件由 2 个按钮和一个显示数据的 ListView 组成。大多数情况下,当小部件提供程序的 onUpdate 方法被调用时,一切都会正常加载并且大家都很高兴。 但是我注意到有时在调用更新方法后
我是一名优秀的程序员,十分优秀!