在SearchView的OnQueryTextChange中调用updateUserSection方法。当我快速输入SearchView时,我得到一个ConcurrentModificationException(如果我慢慢输入,它会起作用)。我不能告诉导致这个问题的原因。
public void updateUserSection(String text){
relevantUsers.clear();
for(String key: allUsers.keySet()) {
if ((key.toLowerCase().contains(text.toLowerCase()))) {
relevantUsers.put(key, allUsers.get(key));
}
}
// instance is a private reference to this AddTrailsAct, probably doesn't matter
instance.generateButtons();
}
private synchronized void generateButtons() {
usersLayout.removeAllViewsInLayout();
// make the first row
currentRow = new LinearLayout(getApplicationContext());
// make it pretty
makePretty(currentRow);
// add the first row
usersLayout.addView(currentRow);
// limits 3 buttons per row
rowIndex = 0;
// iterate through relevantUsers and try to find pictures
(new SetButtonTask(relevantUsers)).execute();
}
private class SetButtonTask extends AsyncTask<Void, Void, Void> {
private HashMap<String, String> userList;
private HashMap<String, Bitmap> nameToBitmap = new HashMap<String, Bitmap>();
public SetButtonTask(HashMap<String, String> userList) {
this.userList = userList;
}
@Override
protected Void doInBackground(Void... v) {
for (String name: userList.keySet()) {
putToBitmap(name, userList.get(name));
}
return null;
}
@Override
protected void onPostExecute(Void v) {
// THE RUNTIME ERROR POINTS TO THE LINE BELOW
for (String name: nameToBitmap.keySet()) {
instance.addToUsersLayout(nameToBitmap.get(name), name);
}
}
private void putToBitmap(String name, String id) {
try {
nameToBitmap.put(name, Bitmap.createScaledBitmap(
BitmapFactory.decodeStream((new URL("https://graph.facebook.com/" +
id +
"/picture?type=large")).openConnection().getInputStream()),
200,
200,
true));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
// add button to the usersLayout
private synchronized void addToUsersLayout(final Bitmap profPicBitmap, final String name) {
runOnUiThread(new Runnable() {
@Override
public void run() {
numTasks++;
Log.d("myTag","the UiThread has " + numTasks + " threads running");
// the button we'll be building
final ImageButton b = new ImageButton(getApplicationContext());
b.setImageBitmap(profPicBitmap);
// touch animation
b.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// set filter when pressed
if (event.getAction() == MotionEvent.ACTION_DOWN) {
b.setColorFilter(new
PorterDuffColorFilter(getResources().getColor(R.color.skyBlue),
PorterDuff.Mode.MULTIPLY));
}
// handle "click"
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("myTag", "imageButton pressed");
// add the trail
((Project_18) getApplication()).getMe().addTrail(fb, relevantUsers.get(name));
}
// remove filter on release/cancel
if (event.getAction() == MotionEvent.ACTION_UP ||
event.getAction() == MotionEvent.ACTION_CANCEL) {
b.clearColorFilter();
}
return true;
}
});
// contains button and name of the user
LinearLayout buttonLayout = new LinearLayout(getApplicationContext());
// make button look good and add to buttonLayout
makePretty(b, name, buttonLayout);
// add to buttonMap
buttonMap.put(name, buttonLayout);
// add buttonLayout to row
currentRow.addView(buttonLayout);
// row index handling
if (rowIndex < 2) {
rowIndex ++;
} else {
// reset index
rowIndex = 0;
// make new row
currentRow = new LinearLayout(getApplicationContext());
makePretty(currentRow);
// add new row to the layout
usersLayout.addView(currentRow);
}
numTasks--;
}
});
}