Android - android.os.NetworkOnMainThreadException
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!!
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
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.setOnClickListener
abajo,
SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
Referencias
Documento AsyncTask
Ejemplo de AsyncTask en Android
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}