Android - android.os.NetworkOnMainThreadException

Resuelto GeekedOut asked hace 54 años • 10 respuestas

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

¿Cómo solucionar android.os.NetworkOnMainThreadException?

Ya agregué esta línea a mi manifiesto:

<uses-permission android:name="android.permission.INTERNET" />

En esa discusión, hablan de que el hilo de ejecución principal de la aplicación no puede conectarse en red. 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<NameValuePair> postParameters = new ArrayList<NameValuePair>();  
        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!!

GeekedOut avatar Jan 01 '70 08:01 GeekedOut
Aceptado

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

Debe llamar al método sendfeedback en asynctask, entonces solo funcionará el código anterior. Como el servidor web tarda mucho en responder, el hilo principal deja de responder. Para evitarlo deberías llamarlo en otro hilo. Por tanto, asynctask es mejor.

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

 avatar Feb 23 '2012 15:02

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

Para solucionarlo, puede utilizar una clase interna privada dentro de su Actividad que se extienda android.os.AsyncTask<Params, Progress, Result>y que hará las llamadas al servidor.

Algo como,

private class SendfeedbackJob extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String[] params) {
        // do above Server call here
        return "some message";
    }

    @Override
    protected void onPostExecute(String message) {
        //process message
    }
}

Y luego invocar la clase anterior desde submit.setOnClickListenerabajo,

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

tarea asíncrona

Referencias

Documento AsyncTask

Ejemplo de AsyncTask en Android

prayagupa avatar Jan 05 '2015 21:01 prayagupa
if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
AnDx avatar Jun 12 '2013 11:06 AnDx