【问题标题】:NoSuchElementException thrown from ListView从 ListView 抛出 NoSuchElementException
【发布时间】:2016-10-23 11:14:30
【问题描述】:

我有一个 ListView,我将一个空适配器传递给它,然后在从服务器拉取数据后填充它:

Context mContext;
List<Recipe> menuList = new ArrayList<>();
private Party party;

public MenuAdapter(Context context) {
    mContext = context;
    party = PartyPlannerConfig.getCurrentParty();
}

public void replaceList(final @NonNull List<Recipe> menuList) {
    this.menuList = menuList;
    notifyDataSetChanged();
}

在我的 getView 方法中,我填充了视图,并且我还在其中一个视图上有了一个点击监听器,它从一个单独的列表中添加/删除项目,而不是填充适配器的列表:

 @Override
public View getView(int position, View convertView, final ViewGroup parent) {
    final View view = LayoutInflater.from(mContext).inflate(R.layout.content_recipe_element, parent, false);

    final TextView mButton = (TextView) view.findViewById(R.id.name);
    final ImageView mImage = (ImageView) view.findViewById(R.id.image);
    final ImageView mBtnFavourite = (ImageView) view.findViewById(R.id.btn_favourite);

    final Recipe recipe = getItem(position);
    Picasso.with(mContext).load(recipe.getTableImageURL()).into(mImage);
    mButton.setText(recipe.getRecipeName());

    final List<Recipe> currentRecipes = new ArrayList<>(party.getMenuItems());
    final List<Recipe> modifiedRecipes = new ArrayList<>(party.getMenuItems());

    mBtnFavourite.setSelected(currentRecipes.contains(recipe));

    mBtnFavourite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                if (!mBtnFavourite.isSelected()) {
                    modifiedRecipes.add(recipe);
                } else {
                    if (modifiedRecipes.contains(recipe)) {
                        modifiedRecipes.remove(recipe);
                    }
                }
                party.setMenuItems(modifiedRecipes);
                notifyDataSetChanged();
                new SavePartyTask().execute(party);
            } catch (Exception ignore) { }
        }
    });

    mImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mContext.startActivity(RecipeDetailActivity.makeIntent(mContext, recipe));
        }
    });

    return view;
}

由于某种原因,当我一遍又一遍地单击 mBtnFavourite 时,我得到了 NoSuchElementException:

AndroidRuntime:...
                  java.util.NoSuchElementException
                                                                               at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576)
                                                                               at com.backendless.FootprintsManager$Inner.updateFootprintForObject(FootprintsManager.java:257)
                                                                               at com.backendless.Persistence$4.handleResponse(Persistence.java:196)
                                                                               at com.backendless.async.message.AsyncMessage$ResponseHandler.handle(AsyncMessage.java:64)
                                                                               at com.backendless.async.message.AsyncMessage.handleCallback(AsyncMessage.java:41)
                                                                               at com.backendless.core.AndroidCarrier$1.handleMessage(AndroidCarrier.java:37)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:98)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

下面是我的 AsyncTask 代码:

private class SavePartyTask extends AsyncTask<Party, Void, Void> {
    @Override
    protected Void doInBackground(Party... params) {
        new PartyController(mContext).saveParty(params[0]);
        return null;
    }
}

这是 PartyController 的代码:

公共类 PartyController 扩展控制器 {

private static PartyController instance;

public PartyController(Context context) {
    super(context);
}

public synchronized static PartyController getInstance(Context context) {
    if(instance == null) {
        instance = new PartyController(context);
    }
    return instance;
}

public void getPartyList() throws UserException {
    mJobManager.addJobInBackground(new GetPartyListJob());
}

public void addParty(String partyName, Occasion occasion, Moodboard inspiration) throws UserException {
    final Party party = new Party();
    final Long currentTime = (System.currentTimeMillis() / 1000L);

    party.setName(partyName);
    party.setCreated(currentTime);
    party.setOccasion(occasion);
    party.setMoodboard(inspiration);

    final Calendar c = Calendar.getInstance();
    party.setUpdated(c.getTimeInMillis());

    PartyPlannerLog.v(WHOAMI, "Logged in user: " + Backendless.UserService.loggedInUser());
    mJobManager.addJobInBackground(new SavePartyJob(party));
}

public void deleteParty(Party party) throws UserException {
    mJobManager.addJobInBackground(new DeletePartyJob(party));
}

public void saveParty(Party party) {
    final Calendar c = Calendar.getInstance();
    party.setUpdated(c.getTimeInMillis());
    PartyPlannerConfig.setCurrentParty(party);
    mJobManager.addJobInBackground(new SavePartyJob(party));
}

} 我此时非常困惑,并且一整天都在试图解决这个问题。请帮忙!!!

【问题讨论】:

  • 请张贴您的异步任务代码和聚会课程。

标签: android listview adapter backendless


【解决方案1】:

是的,它看起来像一个并发问题。仔细调试您的代码,根据标志在列表中添加和删除项目。我想,此刻您的代码试图删除不存在的元素。使用 logger 跟踪列表中的项目,并检查您是否正在调用一个空 List 。

【讨论】:

    【解决方案2】:

    我认为您遇到了并发问题:

    party.setMenuItems(modifiedRecipes);
    new SavePartyTask().execute(party);
    

    这里是:

    PartyPlannerConfig.setCurrentParty(party);
    mJobManager.addJobInBackground(new SavePartyJob(party));
    

    我不确定这两个函数的作用,但如果它们保留对列表的引用而不是制作副本,那么您可能正在后台线程中访问列表,而 UI 线程会修改按钮上的列表点击。

    这里的一个简单解决方案是在您的派对对象中复制您的列表,而不是保留对原始列表的引用:

    party.setMenuItems(modifiedRecipes);
    

    确保此 setMenuItems 复制 modifiedRecipes 而不是保留对原始的引用。

    【讨论】:

    • 谢谢。我认为并发实际上是这里的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多