在我的主线程中使用AsyncTask(Android)中的“OnProgressUpdate”中的信息

时间:2013-12-17 17:44:30

标签: java android sockets android-asynctask

我正在使用正在侦听服务器的AsyncTask,并在每次收到消息时生成publishProgess(receivedMessage),因此我将特定消息保存在“ArrayList messageStrings;”字段中。

现在我想从AsyncTask类的Outside访问“messageStrings”-Arraylist,但当然我得到一个“concurrentmodificationexception”-Error。

我试图“同步”所有使用它的功能,但我不会帮忙。

那么如何正确处理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);}

2 个答案:

答案 0 :(得分:2)

您的ConcurrentModificationExceptionAsyncTask无关。在Ui线程中调用onProgressUpdate并且它不与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,因为所有内容都已向前移动了一次。

答案 1 :(得分:0)

试试这个......

public volatile ArrayList<String> stringList;

commandList = serverConnection.readIn.getStringList();
synchronized (commandList) {
        Iterator<String> iterator = commandList.iterator();
        while (iterator.hasNext()) {
            String string = (String) iterator.next();
            if(string.startsWith("71 53 11 40")) {
                 CofKleinEsp = Integer.decode(item.substring(12));
                 System.out.println(CofKleinEsp);
                 iterator.remove();
            }
        }
    }

如果变量非易失性,则线程可以创建变量的本地内部副本。 volatile表示不创建本地内部副本的线程...