TextView остается прежним, ему не присваивается новое значение

Я сталкиваюсь с проблемой: при нажатии кнопки я пытаюсь прочитать DataInputstream, в который поступают данные, и отобразить данные.

Я использую цикл while для чтения данных. Но динамическое обновление Textview не происходит.

TextView datatextview = (TextView)findViewById(R.id.data); 

DataInputStream Din = new DataInputStream(socket.getInputStream());
Button getData= (Button)findViewById(R.id.getdata);
getData.setOnClickListener(new OnClickListener() {
    public void onClick(View v) { 
    //.......stuff .......
    try{
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];
    int bytesRead = -1;
    String message1 = "";
    while (true) {
        message1 = "";
        data = Din.readLine();
        bytesRead = (reading).length();
        if (bytesRead != -1) {
            Log.v(TAG,"data"+data); //I'm getting the data correctly
            //But not able to update it in the TextView :(
            datatextview.setText(data);  //doesnt work
        }
    }

2 ответа

Решение

Вы должны выйти из своего метода и отказаться от управления потоком пользовательского интерфейса, чтобы обновить ваши представления. Для этого вам, вероятно, следует использовать AsyncTask с его функцией обновления прогресса, чтобы не перегружать поток пользовательского интерфейса.

Что-то вроде:

public class MyTask extends AsyncTask<Void, String, Void> {
  private final TextView progress;

  public MyTask(TextView progress) {
    this.progress = progress;
  }

  @Override
  protected void onPreExecute() {
    progress.setText("Starting...");
  }

  @Override
  protected Void doInBackground(Void... unused) {
    ... your buffer code, including publishProgress(data); in your while loop ...
  }

  @Override    
  protected void onProgressUpdate(String... data) {
    progress.setText(data[0]);
    progress.invalidate(); // not sure if this is necessary or not
  }

  @Override
  protected void onPostExecute(Void unused) {
    progress.setText("Finished!");
  }
}

Затем вы можете создать и выполнить AsyncTask, используя:

new MyTask(datatextview).execute();

Редактировать - обязательно используйте @Override который помогает предупредить вас, если ваши сигнатуры методов не верны.

Мэтью прямо здесь, но чтобы уточнить...

Если вы делаете это из потока, вы, вероятно, застряли в цикле так быстро, что пользовательский интерфейс никогда не сможет перерисовать ваши новые значения. Если вы хотите принудительно перерисовать пользовательский интерфейс из вызова потока View.invalidate(),

Если вы делаете это из основного потока (который вы должны обязательно пересмотреть), то вы застряли в цикле, а пользовательский интерфейс не может перерисовать... вы бы хотели, чтобы все View.postInvalidate() заставить перерисовать пользовательский интерфейс.

Другие вопросы по тегам