Update Textview Android Using Handler

Asked

Viewed 762 times

0

I started Programming now on Android, and I need to update a Textview after receiving a string from a Socket connection. I get the string correctly but the apk closes giving an exception:

10-01 11:05:57.470: E/androidruntime(753): FATAL EXCEPTION: Thread-94

I saw that this exception is caused by updating the ui by a thread outside the main thread, in that the serial solution use Handler to update the ui, however I could not get an example of how to do this and would like to help to implement it in my code:

Searching the web, I found a simple way using a thread apart to update the ui, in the following codigods I show what I did:

Update Class xto(thread that has the function of changing text in Textview)

package com.example.palioteste;

public class AtualizarTexto implements Runnable {

            private String text;

            public AtualizarTexto(final String text) {
                this.text = text;
            }

            @Override
            public void run() {

                MainActivity.textorecebido.setText(text);
            }

        }

Mainactivity

    package com.example.palioteste;

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket;
    import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView;

    public class MainActivity extends Activity {

    private Button button;
    private TextView textView1;
    static TextView textorecebido;

    @Override   
    protected void onCreate(Bundle savedInstanceState) {        
        super.onCreate(savedInstanceState);         
        setContentView(R.layout.activity_main);
        button = (Button) findViewById(R.id.button);        
        textView1 = (TextView)  findViewById(R.id.textView1);
        textorecebido = (TextView) findViewById(R.id.textorecebido);

        button.setOnClickListener(new OnClickListener() {           
            @Override           
            public void onClick(View arg0) {
                textView1.setText("Botao Cliquado");
                abrirSocket rodar = new abrirSocket();
                rodar.execute();            
            }
            });     
        }

    @Override   
    public boolean onCreateOptionsMenu(Menu menu) {         
        // Inflate the menu; this adds items to the action bar if it is present.        
        getMenuInflater().inflate(R.menu.main, menu);       
        return true;    
    }

    @Override   
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will      
        // automatically handle clicks on the Home/Up button, so long       
        // as you specify a parent activity in AndroidManifest.xml.         
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }       
            return super.onOptionsItemSelected(item);
        } 
}

Thread that makes the socket connection

package com.example.palioteste;

import android.os.AsyncTask;

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.net.Socket; 
import java.util.Arrays;

public class abrirSocket extends AsyncTask { 
private static final String hostname = "192.168.43.127"; 
private static final int portaServidor = 9837; 
int valorconvertido;

    @Override
    protected String doInBackground(String... params) {
    try {
        Socket socket = new Socket(hostname, portaServidor);

        //dados enviados para o servidor

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("2");
        bw.newLine();
        bw.flush();

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //String retorno =  "Dados Recebidos " + br.readLine(); //retornar ok

        Thread t = new Thread(new AtualizarTexto(br.readLine()));
        t.start();
        // socket.close();
    }
    catch(IOException e) {
        return e.getMessage();
    }
    return null;

    }     
}

This implementation did not work and I want to try to use Handler, but the examples I found I could not adapt to my code and I ask the members for help for this.

1 answer

2

You can use this method to run on the UI thread

runOnUiThread(new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            textorecebido.setText(text);
        }

    });

Or you can use the Asynctask methods that also wheels on the main thread as shown in the link

Try this:

'@Override
protected String doInBackground(String... params) {
    try {
        Socket socket = new Socket(hostname, portaServidor);

        //dados enviados para o servidor

        BufferedWriter bw = new BufferedWriter(new     OutputStreamWriter(socket.getOutputStream()));
        bw.write("2");
        bw.newLine();
        bw.flush();

        BufferedReader br = new BufferedReader(new    InputStreamReader(socket.getInputStream()));
    //String retorno =  "Dados Recebidos " + br.readLine(); //retornar ok

        return br.readLine();

       // socket.close();

    }
    catch(IOException e) {
        return e.getMessage();
    }         return null;
}

@Override
protected void onPostExecute(String resultado) {

    //...
    seuTextview.setText(resultado());
}    
  • Creonilso thanks for the quick contact, give me only an example of implementation of this code that passed me, as I would put in the code!

  • This is an Activity method, so you will have to call inside an Activity or if it is in another class you will have to pass the context(Activity). Then just copy this code I gave you and replace this //text snippet.setText(text) with the code you run on the main thread, no matter what thread you’re on the UI will be updated.

  • Creonilson, I’m picking up a little bit here and I’ve done a lot of research, and I haven’t figured it out yet. The method he passed me had already seen and had not been able to implement, even more now that Voce said that enters context. You could help me just to implement in the code, because for me it has already been of great value!

  • I edited using the example using asynctask, testa ai

  • Creonilson actually I already tried to use this method onPostExecute, it returns me null, I think and because the connection has already been closed on the server side soon it returns nothing. What I’ve tried is: The separate thread method returns the value of the connection but gives the excesses I explained. the onPostExecute method returns the null value, and I tried onPostUpdate which I think is correct, but I could not implement (nor even update the ui), has some example of onProgressUpdate

  • You did this: Return br.readline(); and yet the value was null?

  • Creonilso, beginner error! I removed the Return null and it worked perfectly, now the ui updates without errors! Thank you very much and for the help!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.