Android – android.os.NetworkOnMainThreadException

У меня есть это исключение, и я читал эту тему, и это показалось мне непонятным:

Как исправить android.os.NetworkOnMainThreadException?

Я уже добавил эту строку в свой манифест:

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

На этом обсуждении они говорят о том, что основной поток выполнения приложения не способен выполнять сетевые взаимодействия. Мне интересно, как реструктурировать мой код, чтобы он был встроен в хорошие практики Android.

Вот мой класс активности для этого:

 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()); } } } 

Что я делаю неправильно здесь и как я могу это исправить? 🙂 Благодаря!!

NetworkOnMainThreadException: исключение, которое возникает, когда приложение пытается выполнить сетевую операцию в своем основном потоке.

Вы должны вызвать метод sendfeedback в asynctask, тогда только над кодом будет работать. Поскольку веб-сервер занимает много времени, чтобы ответить, основной поток становится невосприимчивым. Чтобы этого избежать, вы должны называть его другим. Следовательно, асинтекст лучше.

Здесь ссылка, которая иллюстрирует использование asynctask

NetworkOnMainThreadException вызывается, когда ваше приложение пытается выполнить сетевую операцию в основном потоке.

Чтобы исправить это, вы можете использовать закрытый внутренний класс в своей деятельности, который расширяет android.os.AsyncTask<Params, Progress, Result> который будет работать с сервером.

Что-то вроде того,

 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 } } 

А затем вызовите выше класс из submit.setOnClickListener как submit.setOnClickListener ниже,

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

AsyncTask

Рекомендации

Документ AsyncTask

Пример Android для AsyncTask

 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()); } 

Вот ваша проблема. Начиная с api 11, это исключение сообщит вам, что вы выполняете длинные задачи в потоке ui (http-связь в вашем классе), и в соответствии с новой политикой StrictGuard это невозможно. Таким образом, у вас есть два разных выбора

  1. Используйте thread или aynctask, чтобы выполнить долгосрочную задачу yout (лучший способ)

Вы сделали сетевой вызов в основном потоке, который противоречит правилам Android, поэтому вам нужно сделать свой сетевой вызов в отдельном потоке, таком как асинтеза или обработчик и т. Д.

Вы можете просто создать класс Async, как показано ниже.

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

Вы можете просто поместить весь код внутри метода doInBackground

Посмотрите на эту ссылку: https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

Исключение, которое возникает, когда приложение пытается выполнить сетевую операцию в своем основном потоке. Приложениям, использующим более ранние версии SDK, разрешено создавать сети в своих потоках цикла основного события, но это сильно обескураживает.

Если вы установите minSdkVersion <11, то ваше приложение будет работать, и вы можете запустить сетевую операцию в основном потоке.