Doubts about the use of Threads, AsyncTask and Handler

0

In this code they use threads , handlers and AsyncTask , what I do not understand is because they use the 3 and not only threads or handlers , What is the difference? In the code I have commented the reasons and why they were used from my perspective, but I am still very confused.

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Wifi_Information extends AppCompatActivity implements View.OnClickListener {

    private TextView infoview;
    EditText e1;
    EditText e2;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wifi__information);
        Button getinfo = (Button) findViewById(R.id.bwifiinfo);
        getinfo.setOnClickListener(this);
        e1 = (EditText) findViewById(R.id.editText2);
        e2 = (EditText) findViewById(R.id.bmensaje);
        tv = (TextView) findViewById(R.id.textView);

        Thread mythread = new Thread(new MyServer());
        mythread.start();

        infoview = findViewById(R.id.infoView);
    }
    //Esta clase lo que hace es simplemente crear el servidor
    //Y ponerlo disponible
    //Runnable solo es una interfaz que necesita para instanciar un hilo para contenerlo
    class MyServer implements Runnable {

        ServerSocket ss;
        Socket mysocket;
        DataInputStream dis;

        String message;
        Handler handler = new Handler();

        @Override
        public void run() {
            try {
                ss = new ServerSocket(8080);
                //Nos sirve para ejecutar una accion especifica desde un hilo que estemos ejecutando sobre un view
                //Aqui no entiendo porque uso ese handler

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "Esperando al cliente", Toast.LENGTH_LONG).show();
                    }
                });
                while (true) {
                    //El codigo se queda en la siguiente linea hasta que una conexion a nuestro servidor se estableca

                    mysocket = ss.accept();
                    dis = new DataInputStream(mysocket.getInputStream());
                    message = dis.readUTF();

                    handler.post(new Runnable() {
                        @Override
                        public void run() {

                            tv.append("ANDROID:" + message);
                            tv.append("\n");
                        }
                    });

                }

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    //La clase async task nos permite crear acciones en el hilo principal, pero no acceder a sus componentes
    //ente los caracteres <> ponemos los tipos de variables que maneja y devuelve
    //datos que pasaremos al comenzar la tarea, parametros que necesitareos al actualizar la Interfaz+
    //Dato que devolveremos una vez terminada la tarea
    //Usamos async task para poder actualizar la interfaz
    //Porque la interfaz no acepta llamadas desde otros hilos que no sea el suyo
    //Solo para tareas mas pequeñas
    //Y no entiendo porque para esta operacion uso async task
    class BackgroundTask extends AsyncTask<String, Void, String> {

        Socket s;
        DataOutputStream dos;
        String ip, message;

        @Override
        //Esto es un hilo en segundo plano
        //Se encarga de realizar la tarea en segundo plano
        protected String doInBackground(String... params) {
            ip = params[0];
            message = params[1];
            //El ip es la direccion ip del servidor y el puerto al cual esta siendo excuchado

            try {
                //Aqui el socket recibe de parametros el ip de destino y el puerto del servidor
                s = new Socket(ip, 8080);
                dos = new DataOutputStream(s.getOutputStream());
                dos.writeUTF(message);
                dos.close();

            } catch (IOException E) {
                E.printStackTrace();
            }
            return null;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void GetWifiInformation() {
        infoview.setText(" ");
        WifiManager wifimng = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        WifiInfo wifiInfo = wifimng.getConnectionInfo();
        if (isWifiConected()) {
            infoview.append("SSID: " + wifiInfo.getSSID() + "\n");
            infoview.append("BSSID(ACCESS POINT): " + wifiInfo.getBSSID() + "\n");
            infoview.append("LINK SPEED: " + String.valueOf(wifiInfo.getLinkSpeed()) + "\n");
            //No funciona en android M o superior
            infoview.append("YOUR MAC ADDRESS: " + this.getMacAddress() + "\n");
            infoview.append("IP ADDRESS: " + getIpAddress() + "\n");
            infoview.append("DNS 1: " + getDns(1) + "\n");
            infoview.append("DNS 2: " + getDns(2) + "\n");
            infoview.append("CHANNEL: " + getChannel(wifiInfo.getFrequency()));

        } else {
            Toast.makeText(this, "NO WIFI CONECTION", Toast.LENGTH_LONG).show();
        }

    }

    @Override
    public void onClick(View view) {

        switch (view.getId()) {
            case (R.id.bwifiinfo): {
                BackgroundTask b = new BackgroundTask();
                //Verificar que el ip sea el mismo
                b.execute(e1.getText().toString(), e2.getText().toString());

                break;
            }

            default: {
                break;
            }
        }
    }
}
    
asked by Diego Alejandro Uribe Blatnik 06.05.2018 в 17:33
source

1 answer

0

In class MyServer :

class MyServer implements Runnable {
    ...

    @Override
    public void run() {
        ...
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(), "Esperando al cliente", Toast.LENGTH_LONG).show();
                }
            });
    }
}

If the handler was not used to display the Toast an exception of the type would be thrown:

  

java.lang.RuntimeException: Can not toast on a thread that has not called Looper.prepare ()

When executed through a handler the code is executed in the Looper associated with the thread and the error does not occur.

Below it was not necessary to use AsyncTask for communication with sockets, you could have used a thread , there is no interaction with the user interface.

    
answered by 09.05.2018 / 05:39
source