TextView остается прежним, ему не присваивается новое значение - PullRequest
2 голосов
/ 16 марта 2011

Я столкнулся с проблемой, при нажатии кнопки я пытаюсь прочитать 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 ]

4 голосов
/ 16 марта 2011

Вы должны выйти из своего метода и отказаться от управления потоком пользовательского интерфейса, чтобы обновить ваши представления.Для этого вам, вероятно, следует использовать 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();

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

0 голосов
/ 16 марта 2011

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

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

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

...