我正在使用一个正在监听服务器的 AsyncTask,并在每次收到消息时发出一个publishProgess(receivedMessage),因此我将特定消息保存在“ArrayList messageStrings;”字段中。
现在我想从 AsyncTask 类之外访问“messageStrings”-Arraylist,但当然我得到了“concurrentmodificationexception”-错误。
我尝试“同步”使用它的所有功能,但我无济于事。
那么如何正确处理 AsyncTask 中的消息?
代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import android.os.AsyncTask;
public class ReadInStream extends AsyncTask<Object, String, Object> {
Socket socket;
public ArrayList<String> stringList;
//Socket der Verbindung
public ReadInStream(Socket socket) {
this.socket = socket;
this.stringList = new ArrayList<String>();
}
@Override
protected Object doInBackground(Object... arg0) {
try {
System.out.println("Thread ReadInStream started.");
BufferedReader inStream = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
while (true) {
// jede Zeile einlesen und überprüfen, ob sie etwas enthaelt
String inputLine = inStream.readLine();
if (inputLine != null && inputLine.trim() != ""
&& inputLine.length() > 0) {
System.out.println("Recieved: " + inputLine);
publishProgress(inputLine);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
@Override
protected synchronized void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
stringList.add(values[0]);
}
public synchronized ArrayList<String> getStringList(){
return this.stringList;
}
}
<小时/>我称之为:
commandList = serverConnection.readIn.getStringList();
for(String item: commandList){
if (item.startsWith("71 53 11 40")){
CofKleinEsp = Integer.decode(item.substring(12));
System.out.println(CofKleinEsp);
commandList.remove(item);}
最佳答案
您的ConcurrentModificationException
与该AsyncTask
无关。 onProgressUpdate
在 Ui 线程内调用,并且它不与 doInBackground
共享任何可变状态。如果只有 ui 线程接触 stringList
,则不需要同步。
你的问题是
for (String item : commandList) {
commandList.remove(item);
}
您在迭代列表时修改列表。这也是并发修改。要解决这个问题,请使用Iterator
删除项目。这样迭代器(上面也隐式使用)就会知道元素何时被删除,并且不会再提示。
for (Iterator<String> iterator = commandList.iterator(); iterator.hasNext();) {
String item = iterator.next();
iterator.remove();
}
第二个选项是使用索引循环并从后面遍历列表。
for (int i = commandList.size() - 1; i > 0; i--) {
commandList.remove(i);
}
您也可以从头到尾执行此操作,但随后您将不得不处理不断变化的索引。删除 i
后,下一次迭代必须再次处理 i
,因为所有内容都从一开始就移动了一个。
关于java - 在我的主线程中的 AsyncTask(Android) 中使用 "OnProgressUpdate"之外的信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20641144/