Android – android.os.NetworkOnMainThreadException

Tengo esta excepción y estaba leyendo un hilo sobre esto, y me pareció confuso:

Cómo arreglar android.os.NetworkOnMainThreadException?

Ya agregué esta línea a mi manifiesto:

 

En esa discusión, hablan sobre el hilo principal de ejecución de la aplicación que no puede hacer networking. Lo que me pregunto es cómo reestructurar mi código para que esté en línea con las buenas prácticas de Android.

Aquí está mi clase de Actividad para esto:

 package com.problemio; import java.io.InputStream; import java.util.ArrayList; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; public class LoginActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); // Show form for login_email final EditText loginEmail = (EditText) findViewById(R.id.login_email); String name = loginEmail.getText().toString(); // Show field for password final EditText password = (EditText) findViewById(R.id.password); String text = password.getText().toString(); // Show button for submit Button submit = (Button)findViewById(R.id.submit); // Show options for create-profile and forgot-password submit.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { String email = loginEmail.getText().toString(); String pass = password.getText().toString(); sendFeedback(pass, email); } }); } public void sendFeedback(String pass , String email) { Log.d( "1" , pass ); Log.d( "1" , email ); // Go to db and check if these r legit // How do I do that? :) ArrayList postParameters = new ArrayList(); postParameters.add(new BasicNameValuePair("username", email )); postParameters.add(new BasicNameValuePair("password", pass )); String responseString = null; try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("myUrl"); // no idea what this does :) httppost.setEntity(new UrlEncodedFormEntity(postParameters)); // This is the line that send the request HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); } catch (Exception e) { Log.e("log_tag", "Error in http connection "+e.toString()); } } } 

¿Qué estoy haciendo mal aquí y cómo podría solucionarlo? 🙂 ¡¡Gracias!!

NetworkOnMainThreadException: la excepción que se produce cuando una aplicación intenta realizar una operación de red en su hilo principal.

Debería llamar al método sendfeedback en asynctask y solo el código anterior funcionará. Como el servidor web está tardando mucho tiempo en responder, el hilo principal deja de responder. Para evitarlo, debe llamarlo en otro hilo. Por lo tanto, asynctask es mejor.

aquí hay un enlace que ilustra cómo usar asynctask

NetworkOnMainThreadException se lanza cuando su aplicación intenta la operación de red en el hilo principal.

Para solucionarlo, puede usar una clase interna privada dentro de su Actividad que extienda android.os.AsyncTask que hará que el servidor llame a productos.

Algo como,

 private class SendfeedbackJob extends AsyncTask { @Override protected String doInBackground(String[] params) { // do above Server call here return "some message"; } @Override protected void onPostExecute(String message) { //process message } } 

Y luego invoque sobre clase desde submit.setOnClickListener como se muestra a continuación,

 SendfeedbackJob job = new SendfeedbackJob(); job.execute(pass, email); 

AsyncTask

Referencias

AsyncTask doc

Ejemplo AsyncTask Android

 if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } 
  try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("myUrl"); // no idea what this does :) httppost.setEntity(new UrlEncodedFormEntity(postParameters)); // This is the line that send the request HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); InputStream is = entity.getContent(); } catch (Exception e) { Log.e("log_tag", "Error in http connection "+e.toString()); } 

Aquí está tu problema Desde la API 11, esta excepción le informará que está ejecutando tareas largas en el hilo de la interfaz de usuario (la comunicación http en su clase), y de acuerdo con la nueva política de StrictGuard esto no es posible. Entonces tienes dos opciones diferentes

  1. Use thread o aynctask para ejecutar su tarea a largo plazo (mejor forma)

Hiciste una llamada de red en el hilo principal que está en contra de las reglas de Android, por lo que tienes que hacer tu llamada de red en un hilo separado como asynctask o controlador, etc.

Puedes simplemente crear una clase Async como se muestra a continuación

 class Retrievedata extends AsyncTask { @Override protected String doInBackground(String... params) { try{ //Your code } return null; } } 

Puedes poner todo tu código dentro del método doInBackground

mira este enlace: https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

La excepción que se produce cuando una aplicación intenta realizar una operación de red en su hilo principal. Las aplicaciones que se dirigen a versiones anteriores de SDK pueden hacer redes en sus hilos de bucle de eventos principales, pero se desaconseja en gran medida.

si configura minSdkVersion <11, su aplicación funcionará y podrá ejecutar la operación de red en el hilo principal.

El hilo principal es el hilo de la interfaz de usuario y no se puede hacer una operación en el hilo principal que pueda bloquear la interacción del usuario. Para evitar esto, crea un controlador simple y actualiza el hilo principal si lo deseas.

 Runnable runnable; Handler newHandler; newHandler = new Handler(); runnable = new Runnable() { @Override public void run() { try { //update UI } catch (Exception e) { e.printStackTrace(); } } }; runnable.run(); 

para detener el uso de hilo

newHandler.removeCallbacks (ejecutable);

Para más información mira esto. https://android-developers.googleblog.com/2009/05/painless-threading.html

Después de una larga investigación (duró medio día), he encontrado una solución para mi problema que es similar al problema indicado aquí. La excepción que muestra mi Android Studio 2.3.3 fue esta:

android studio android.os.networkonmainthreadexception

El problema se basaba en la imposibilidad de establecer una variable de UI en MainActivity. Entonces vi el siguiente video y resolví mi problema. Espero que también sea útil para otros:

Cómo evitar el sistema operativo Android NetworkOnMainThreadException