Java 通过Intent将数据从应用程序传递到小部件时的空指针

Java 通过Intent将数据从应用程序传递到小部件时的空指针,java,android,android-recyclerview,widget,Java,Android,Android Recyclerview,Widget,我有一个使用改型检索的食谱列表。然后我得到配方名称,我想更新与我的应用程序关联的小部件,以显示所选的recipeName。recipeName反映在下面我的RecyclerView适配器中 当用户单击RecylcerView中的某个项目时,我想更新我为应用程序提供的关联小部件 下面是用于RecyclerView的适配器,其中我有.setOnClickListener()方法,并通过Intent传递我的所有数据 @Override public void onBindViewHol

我有一个使用改型检索的食谱列表。然后我得到配方名称,我想更新与我的应用程序关联的小部件,以显示所选的
recipeName
recipeName
反映在下面我的
RecyclerView
适配器中

当用户单击
RecylcerView
中的某个项目时,我想更新我为应用程序提供的关联小部件

下面是用于
RecyclerView
的适配器,其中我有
.setOnClickListener()
方法,并通过
Intent
传递我的所有数据

        @Override
public void onBindViewHolder(@NonNull MyAdapter.ViewHolder holder, final int position) {
        String id = mRecipeDataSet.get(position).getId();
        //The recipe name I want to pass to my widget
        final String recipeName = mRecipeDataSet.get(position).getName();
        holder.mTextView.setText(id);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(con, BakingWidgetProvider.class);
                intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                int[] ids = AppWidgetManager.getInstance(con).getAppWidgetIds(new ComponentName(con, BakingWidgetProvider.class));
                if(ids != null && ids.length > 0) {
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
                    intent.putExtra(RECIPE_NAME, recipeName);
                    con.sendBroadcast(intent);
                }
                Intent i = new Intent(con, IndividualRecipeActivity.class);
                Bundle bundle = new Bundle();
                bundle.putParcelableArrayList("Recipe_List", (ArrayList<? extends Parcelable>) mRecipeDataSet);
                i.putExtras(bundle);
                i.putExtra("Position",position);
                con.startActivity(i);
            }
        });

}

更新:我已包含代码以包含对
.onReceive()
的覆盖,并在此覆盖方法中设置了字段。然后我尝试使用它更新
.onUpdate AppWidget()
中的接口,但是该小部件没有基于mrecipName字段更新TextView,因为mrecipName字段为空。

您应该在AppWidgetClass中重写onReceive。这将接收广播的意图,以便您可以从中检索数据

@Override
public void onReceive(Context context, Intent intent) {
    super.onReceive(context, intent);
    //Insert code here
}

然后继续添加代码以接收/分配来自Intent的数据。

一旦您通过向您的小部件(类固醇上的BroadcastReceiver)发送广播来触发您的小部件,您就可以从bundle设置字段
mrecipName
,但在设置字段
mrecipName
之前,更新RemoteView(所以此时mRecipeName为空)。这样做:

@Override
public void onReceive(Context context, Intent intent) {
   mRecipeName = intent.getStringExtra(RECIPE_NAME);
   super.onReceive(context, intent);
}
事实上,为了使生产更清洁。制作如下:

Intent intent = new Intent(con, BakingWidgetProvider.class);
intent.setAction("UPDATE_ACTION");
int[] ids = AppWidgetManager.getInstance(con).getAppWidgetIds(new ComponentName(con, BakingWidgetProvider.class));
if(ids != null && ids.length > 0) {
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
      intent.putExtra(RECIPE_NAME, recipeName);
      con.sendBroadcast(intent);
}
您的onReceive将类似于:

@Override
public void onReceive(Context context, Intent intent) {
   if(intent.getAction().equals("UPDATE_ACTION") {
       mRecipeName = intent.getStringExtra(RECIPE_NAME);
       int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
       if (appWidgetIds != null && appWidgetIds.length > 0) {
            this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
       }
   } else {
      super.onReceive(context, intent);
   }
}

您应该使用这个问题的第二个答案中显示的广播:谢谢,我相信我已经成功地设置了它,我只是不知道如何保存信息以及在哪里检索然后传递到我的小部件中的TextView(通过我的WidgetProvider类)。刚刚更新,我无法用适配器类传递的字符串填充UI。看起来很奇怪,但在WidgetProvider类中它可能为null。明白了吗,所以我的方法的顺序很简单?语法本身正确吗?@tccpg288只是更改方法的顺序,似乎这就是问题所在。因为super将触发您的onUpdate()只有在这之后,您才尝试从intent获取receipe名称,但此receipe名称在更新()中使用。如果它对您没有帮助,只需制作一个示例应用程序,社区将尝试找出问题所在。刚刚尝试,它仍然为空。完整代码可在此处获得:Dude,onUpdate()的问题回调不仅仅是由您触发的。这意味着什么?当用户添加新的小部件时,或者是到了更新小部件的时候了,您在baking\u widget\u provider\u info.xml中配置的小部件时,您的onUpdate()回调将被触发,所以如果您自己触发小部件,您将不会得到nullpointer(来自适配器),但一旦用户添加了新的小部件,就没有额外的数据(receipe_name),所以在onUpdate中您将得到nullpointer。onReceive()之外没有任何内容(onUpdate()、onEnabled()等),例如静态数据成员,将是可靠的。将您的信息存储在文件或数据库中。因此,您可以执行以下操作:将receipe_name保存在prefs中,并在onUpdate()中获取它,如果它是空的,则显示类似空视图的内容,如果它不只是使用它并显示您想要的内容
@Override
public void onReceive(Context context, Intent intent) {
   if(intent.getAction().equals("UPDATE_ACTION") {
       mRecipeName = intent.getStringExtra(RECIPE_NAME);
       int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
       if (appWidgetIds != null && appWidgetIds.length > 0) {
            this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
       }
   } else {
      super.onReceive(context, intent);
   }
}