Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android AppWidgetManager方法updateAppWidget无法设置意图、加载数据。这是随机发生的_Android_Android Appwidget - Fatal编程技术网

Android AppWidgetManager方法updateAppWidget无法设置意图、加载数据。这是随机发生的

Android AppWidgetManager方法updateAppWidget无法设置意图、加载数据。这是随机发生的,android,android-appwidget,Android,Android Appwidget,我的小部件由2个按钮和一个显示数据的列表视图组成。大多数时候,当小部件提供者的onUpdate方法被调用时,一切都正常加载,每个人都很高兴 然而,我注意到有时在调用update方法之后,小部件完全无法加载其数据。listview为空,所有按钮都没有响应。这就像我将布局初始化到小部件中一样,但是没有设置任何挂起的意图或列表的适配器 我把一切都记录了下来,发现事实并非如此。与列表适配器一样,每次都会创建挂起的意图,包括失败时的随机时间。很长一段时间以来,我一直认为这与如何将列表数据填充到适配器中有关

我的小部件由2个按钮和一个显示数据的列表视图组成。大多数时候,当小部件提供者的onUpdate方法被调用时,一切都正常加载,每个人都很高兴

然而,我注意到有时在调用update方法之后,小部件完全无法加载其数据。listview为空,所有按钮都没有响应。这就像我将布局初始化到小部件中一样,但是没有设置任何挂起的意图或列表的适配器

我把一切都记录了下来,发现事实并非如此。与列表适配器一样,每次都会创建挂起的意图,包括失败时的随机时间。很长一段时间以来,我一直认为这与如何将列表数据填充到适配器中有关,但每次看到它都能工作,再加上按钮意图不能很好地工作,这让我相信方法updateAppWidget(ComponentName,RemoteView)是失败的。但是,没有错误堆栈可以帮助我确认这一点

下面是在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);
    }
}
这个bug最令人沮丧的是我无法可靠地重新创建它。有时我(不)走运,它露出丑陋的脑袋,其他时候(大多数时候)它工作得很好

另一件我认为有趣的事情是,我在Facebook的小部件中看到了同样的问题。由于保密协议,当我的应用程序出现故障时,我无法显示屏幕,但我可以显示Facebook的相同问题:

当Facebook的widget看起来像这样时,它的问题与我的完全相同。没有加载数据,所有按钮都没有响应

对于Facebook和my widget,后续的更新间隔通常会使问题消失

虽然我很感激我不是唯一一个遇到这个问题的人,但在我解决这个问题之前,我还是不想发布。这里有没有人遇到过这种情况,更好的是找到了解决方案,甚至是问题的原因?谢谢你的帮助

编辑:有趣的东西。我做了一个实验,将更新间隔设置为一整天,而不是每30分钟一次。我的假设是,可能更新方法不是原因,是其他原因导致小部件变为空白和无响应

果然,大约两个小时后,我检查了我的手机,尽管没有调用更新方法,但小部件还是死了。这会让我相信是其他原因导致了这个问题,而不是
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所在的整个区域。如果列表不是空的,我会把信息隐藏起来

这就是正在发生的事情:当工厂被摧毁时(大概是为了内存),小部件本身并没有被摧毁。因此,所有为数据和内容设置意图的代码都没有运行。然而,工厂被重新创建,它运行了一段代码,用新的远程视图对象更新了应用程序小部件。这个远程视图对象没有执行我最初发布的onUpdate()方法中的任何方法,因此它的所有功能都不起作用


故事的寓意:不要在RemoteViewsFactory类中使用
updateAppWidget
!现在,如果您运行所有必要的行,它可能会工作,但我无法确认。

我不确定我的问题是否与您的问题类似,但您可以看看这个堆栈,我无法找到任何解决方案