J'ai cette exception et je lisais un fil sur cela, et cela semblait déroutant:
Comment réparer Android.os.NetworkOnMainThreadException?
J'ai déjà ajouté cette ligne à mon manifeste:
<uses-permission Android:name="Android.permission.INTERNET" />
Dans cette discussion, ils parlent du principal fil d'exécution de l'application qui ne peut pas faire de réseau. Ce que je me demande, c'est comment restructurer mon code afin qu'il soit conforme aux bonnes pratiques d'Android.
Voici ma classe d'activité pour cela:
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'est-ce que je fais mal ici et comment pourrais-je résoudre le problème? :) Merci!!
NetworkOnMainThreadException: Exception levée lorsqu'une application tente d'effectuer une opération de mise en réseau sur son thread principal.
Vous devriez appeler la méthode sendfeedback sur asynctask, alors seul le code ci-dessus fonctionnera. Comme le serveur Web prend beaucoup de temps pour répondre, le fil principal cesse de répondre. Pour l'éviter, vous devriez l'appeler sur un autre thread. Par conséquent, asynctask est meilleur.
voici link qui illustre comment utiliser asynctask
NetworkOnMainThreadException est levé lorsque votre application tente une opération de mise en réseau dans le thread principal.
Pour résoudre ce problème, vous pouvez utiliser une classe interne privée au sein de votre activité qui étend Android.os.AsyncTask<Params, Progress, Result>
, ce qui servira aux appels de serveur.
Quelque chose comme,
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
}
}
Et puis invoquer la classe ci-dessus à partir de submit.setOnClickListener
comme ci-dessous,
SendfeedbackJob job = new SendfeedbackJob();
job.execute(pass, email);
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());
}
Voici votre problème. Depuis api 11, cette exception vous informera que vous exécutez de longues tâches sur le thread d'interface utilisateur (la communication http de votre classe) et, conformément à la nouvelle stratégie StrictGuard, cela n'est pas possible. Donc, vous avez deux choix différents
Vous pouvez simplement créer une classe async comme ci-dessous
class Retrievedata extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try{
//Your code
}
return null;
}
}
Vous pouvez simplement mettre tout votre code dans la méthode doInBackground
Vous avez fait un appel réseau sur le thread principal, ce qui est contraire aux règles Android. Vous devez donc effectuer votre appel réseau sur un thread séparé, comme un asyncte ou un gestionnaire, etc.
Après une longue recherche (une demi-journée), j'ai trouvé une solution à mon problème similaire au problème indiqué ici. L'exception affichée par mon Android Studio 2.3.3 était la suivante:
Android studio Android.os.networkonmainthreadexception
Le problème reposait sur l'impossibilité de définir une variable d'interface utilisateur dans MainActivity. J'ai donc vu la vidéo suivante et j'ai résolu mon problème. J'espère que c'est aussi utile aux autres:
Le thread principal est le thread d'interface utilisateur et vous ne pouvez pas effectuer d'opération dans le thread principal susceptible de bloquer l'utilisateur Interaction.Pour éviter cela, créez un simple gestionnaire et mettez à jour le thread principal si vous le souhaitez.
Runnable runnable;
Handler newHandler;
newHandler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
try {
//update UI
} catch (Exception e) {
e.printStackTrace();
}
}
};
runnable.run();
pour arrêter l'utilisation du fil
newHandler.removeCallbacks (exécutable);
Pour plus d'informations, regardez ceci. https://Android-developers.googleblog.com/2009/05/punset-threading.html
regardez ce lien: https://developer.Android.com/reference/Android/os/NetworkOnMainThreadException.html
Exception levée lorsqu'une application tente d'effectuer une opération de mise en réseau sur son thread principal . Les applications ciblant des versions antérieures du SDK sont autorisées à mettre en réseau leurs threads de boucle d'événements principaux, mais cela est fortement déconseillé.
si vous définissez minSdkVersion <11, votre application fonctionnera et vous pourrez exécuter une opération réseau dans le thread principal.