Java ListView筛选器:非法状态异常
为了理智起见,我将此贴在这里,因为我确信我现在无法独自解决它。我在这里发布了所有需要知道的信息,因为我认为我过去没有解决这个问题的方法是因为我没有发布所有信息。到目前为止,我已经剥离了代码,基本上它是尽可能轻的。但仍然会出现这种错误(尽管非常罕见): 在这篇文章的最底部,我解释了这个错误是什么时候发生的。但首先是代码。我有一个TextWatcher:Java ListView筛选器:非法状态异常,java,android,listview,filter,illegalstateexception,Java,Android,Listview,Filter,Illegalstateexception,为了理智起见,我将此贴在这里,因为我确信我现在无法独自解决它。我在这里发布了所有需要知道的信息,因为我认为我过去没有解决这个问题的方法是因为我没有发布所有信息。到目前为止,我已经剥离了代码,基本上它是尽可能轻的。但仍然会出现这种错误(尽管非常罕见): 在这篇文章的最底部,我解释了这个错误是什么时候发生的。但首先是代码。我有一个TextWatcher: edSearch.addTextChangedListener(new TextWatcher() { @Over
edSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
String text = null;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
text = s.toString();
}
@Override
public void afterTextChanged(final Editable s) {
if (text != null && !text.equals(s.toString())) {
adapter.getFilter().filter(s.toString());
}
text = null;
}
});
此线程在一旁运行,每200毫秒触发一次textwatcher。我会疯狂地手动测试:
new Thread(new Runnable() {
public void run() {
Runnable r = new Runnable() {
public void run() {
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_S));
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_S));
}
};
Runnable r2 = new Runnable() {
public void run() {
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_DEL));
dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_DEL));
}
};
while (true) {
runOnUiThread(r);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
ExceptionHandler.handle(e);
}
runOnUiThread(r2);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
ExceptionHandler.handle(e);
}
}
}
}).start();
}
这是我的适配器:
private class ArrayAdapterEinsatz extends DynamicArrayAdapter<Einsatz> {
public ArrayAdapterEinsatz(int textViewResourceId) {
super(ListEinsaetze.this, textViewResourceId, new ArrayList<Einsatz>());
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Einsatz einsatz = getFilteredItems().get(position);
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = ListEinsaetze.this.getLayoutInflater();
rowView = inflater.inflate(R.layout.eintrag_einsatz, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.tvId = (TextView) rowView.findViewById(R.id.eeinsatzid);
viewHolder.tvDatumVonbis = (TextView) rowView.findViewById(R.id.eeinsatzvonbis);
viewHolder.tvKundenName = (TextView) rowView.findViewById(R.id.eeinsatzkundenname);
viewHolder.tvKundenOrt = (TextView) rowView.findViewById(R.id.eeinsatzort);
viewHolder.tvEntfernung = (TextView) rowView.findViewById(R.id.eeinsatzentfernung);
viewHolder.iveRotate = (ImageViewEffects) rowView.findViewById(R.id.eeinsatzrotate);
viewHolder.iveRotate.setBitmap(Utils.drawableToBitmap(R.drawable.ic_refresh_1, 22), ImageViewEffects.ROTATE);
viewHolder.ivAnsprechpartnerVorhanden = (ImageView) rowView.findViewById(R.id.eeinsatzimageansprechvorhanden);
viewHolder.ivBelegeVorhanden = (ImageView) rowView.findViewById(R.id.eeinsatzimagebelegevorhanden);
viewHolder.ivTaetigkeitVorhanden = (ImageView) rowView.findViewById(R.id.eeinsatzimagetaetigkeitvorhanden);
rowView.setTag(viewHolder);
}
final ViewHolder holder = (ViewHolder) rowView.getTag();
return rowView;
}
}
在TextWatcher中,按住F8(continue)键(这似乎会给程序流程带来不规则,我只能想象?)。如果没有断点,则不会发生错误
顺便说一句,如果我把
adapter.notifyDatasetChanged()
之后
同样的错误100%都会发生(我知道在publishResults中调用notifyDatasetChanged,所以我不知道)
我不需要它,但它仍然是正确的行为吗?)
TL;医生:
我的代码(尤其是基本适配器代码)是故障安全的吗?(不可能,否则不会发生错误)
编辑:
如果未设置断点,则也会发生错误。我刚得到一个断点…请尝试移动您的断点
adapter.getFilter().filter(s.toString());
以可运行的方式将行插入到具有view.post()的ui线程
它“可能”解决您的问题。不要添加文本观察程序,只需将适配器设置为编辑文本,如下所示 edSearch.setAdapter(适配器) 并重写公共过滤器getFilter()和 受保护的无效publishResults(CharSequence约束、FilterResults结果)
方法
这将解决您的问题..遇到相同的问题,并以这种方式解决:)此代码正在多个线程上运行,因此当您中断该行时,我猜它将暂停此线程,而其他线程正在运行,从而导致此错误。至于adapter.notifyDatasetChanged()方法beilg放在adapter.getFilter方法之后,我只能推测类似的情况正在发生。我对android开发一无所知,所以我只是在这里猜测……嗯,我坚信调试器在遇到断点时会停止所有线程(=整个程序)。如果我没有设置断点,程序就会正常运行,并且始终没有错误。当没有设置断点时也会发生错误,我刚得到一个断点。。。这两句话似乎相互矛盾。您是否至少尝试过像我在上一个问题上建议您的那样,使用performFiltering方法复制数据?不,它们并不相互矛盾。我的编辑是正确的。很难知道错误是什么时候发生的,所以当我看到错误发生时,我做了一次编辑,并在没有任何断点的情况下进行了澄清。你可以过滤1000或1000000次,没有错误发生,然后它就发生了。。。另外,我现在添加了List l=新的ArrayList(m_AllItems);在performFiltering中同步后。仍然会发生错误。@cdbeelala89不,至少在web容器上不会,可能在某个地方有开关。.post是一种视图方法。它向ui线程发布一个可运行的单线程。
adapter.getFilter().filter(s.toString());
adapter.notifyDatasetChanged()
adapter.getFilter().filter(s.toString());
adapter.getFilter().filter(s.toString());