Http android os networkonmainthreadexception

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

У меня возникла ошибка при запуске моего проекта Android для RssReader.

И это показывает ошибку ниже:

Как я могу исправить эту проблему?

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

Как выполнить задачу:

В файле MainActivity.java вы можете добавить эту строку в свой oncreate()

Не забудьте добавить это в файл AndroidManifest.xml :

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

ADD это разрешение в файле android manifest.xml:

Ваше приложение (в местах пятнистого интернет-соединения) перестает отвечать на запросы и блокируется, пользователь воспринимает медленность и должен убить силы, и вы рискуете, что менеджер активности убил ваше приложение и сказал пользователю, что приложение остановлено.

У Android есть несколько хороших советов о хороших практиках программирования для разработки для реагирования: http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

Я решил эту проблему, используя новую Thread .

Вы не можете выполнять сетевой ввод-вывод в потоке пользовательского интерфейса на Honeycomb . Технически это возможно на более ранних версиях Android, но это действительно плохая идея, так как это приведет к тому, что ваше приложение перестанет отвечать на запросы и может привести к тому, что ОС будет убивать ваше приложение за плохое поведение. Вам необходимо запустить фоновый процесс или использовать AsyncTask для выполнения сетевой транзакции в фоновом потоке.

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

Принятый ответ имеет некоторые существенные сторонники. Не рекомендуется использовать AsyncTask для взаимодействия, если вы действительно не знаете, что делаете. Некоторые из сторон включают:

  • AsyncTask, созданный как нестатические внутренние классы, имеет неявную ссылку на окружающий объект Activity, его контекст и всю иерархию View, созданную этим действием. Эта ссылка запрещает сборку Мусора, пока работа в фоновом режиме AsyncTask не завершится. Если соединение пользователя происходит медленно и / или загрузка велика, эти кратковременные утечки памяти могут стать проблемой – например, если ориентация изменяется несколько раз (и вы не отменяете выполняемые задачи), или пользователь переходит к От деятельности.
  • AsyncTask имеет разные характеристики исполнения в зависимости от платформы, на которой он выполняется: до уровня API 4 AsyncTasks выполняется последовательно на одном фоновом потоке; От уровня API 4 до уровня API 10, AsyncTasks выполняется в пуле до 128 потоков; Начиная с уровня API 11, AsyncTask выполняется последовательно на одном фоновом потоке (если вы не используете перегруженный метод executeOnExecutor и не предоставляете альтернативный исполнитель). Код, который отлично работает при серийном запуске ICS, может прерываться при одновременном выполнении на Gingerbread, скажем, если у вас есть непреднамеренные зависимости от порядка выполнения.

Если вы хотите избежать кратковременных утечек памяти, у вас есть хорошо определенные характеристики выполнения на всех платформах и есть основа для создания действительно надежной сетевой обработки, вы можете подумать:

  1. Используя библиотеку, которая хорошо справляется с этим для вас – в этом вопросе есть хорошее сравнение сетевых библиотек или
  2. IntentService этого используйте Service или IntentService , возможно, с помощью PendingIntent чтобы вернуть результат через метод ActivityActivityResult.
Читайте также:  Андроид не определяет симку

Подход IntentService

  • Больше кода и сложности, чем AsyncTask , хотя и не так сильно, как вы думаете
  • Будут очереди запросов и запустить их на один фоновый поток. Вы можете легко контролировать это, заменив IntentService эквивалентной реализацией Service , возможно, как этот .
  • Хм, я не могу сейчас думать о других
  • Избегает проблемы с кратковременной утечкой памяти
  • Если ваша активность перезапускается, когда сетевые операции находятся в полете, она все равно может получить результат загрузки с помощью метода onActivityResult
  • Лучшая платформа, чем AsyncTask для создания и повторного использования надежного сетевого кода. Пример: если вам нужно сделать важную загрузку, вы можете сделать это из AsyncTask в Activity , но если пользовательский контекст отключит приложение для совершения телефонного вызова, система может убить приложение до завершения загрузки. Менее вероятность убить приложение с активной Service .
  • Если вы используете свою собственную параллельную версию IntentService (например, связанную выше), вы можете контролировать уровень параллелизма через Executor .

Резюме реализации

Вы можете реализовать IntentService для выполнения загрузок на одном фоновом потоке довольно легко.

Шаг 1. Создайте IntentService для выполнения загрузки. Вы можете сказать, что загрузить через Intent extra, и передать ему PendingIntent чтобы использовать для возврата результата в Activity :

Шаг 2. Зарегистрируйте службу в манифесте:

Шаг 3. Вызовите службу из Activity, передав объект PendingResult, который служба будет использовать для возврата результата:

Шаг 4: Обработать результат в onActivityResult:

Здесь доступен проект github, содержащий полный рабочий проект Android-Studio / gradle.

  1. Не используйте strictMode (только в режиме отладки)
  2. Не меняйте версию SDK
  3. Не используйте отдельную нить

Использовать службу или AsyncTask

См. Также вопрос переполнения стека:

Android.os.NetworkOnMainThreadException отправляет электронное письмо с Android

Выполнять сетевые действия в другом потоке

И добавьте это в AndroidManifest.xml

Вы отключите строгий режим, используя следующий код:

Это не рекомендуется : используйте интерфейс AsyncTask .

Полный код для обоих методов

Сетевые операции не могут выполняться в основном потоке. Вам нужно запустить все сетевые задачи на дочернем потоке или реализовать AsyncTask.

Вот как вы запускаете задачу в дочернем потоке:

Поместите свой код внутрь:

Использование аннотаций Android – это вариант. Это позволит вам просто запустить любой метод в фоновом потоке:

Обратите внимание, что, хотя он обеспечивает преимущества простоты и удобочитаемости, он имеет свои недостатки.

Это происходит в Android 3.0 и выше. Начиная с Android 3.0 и выше, они ограничили использование сетевых операций (функций, которые обращаются к Интернету) от запуска в потоке основного потока / пользовательского интерфейса (что возникает из ваших методов create и on resume в действии).

Это должно поощрять использование отдельных потоков для сетевых операций. См. AsyncTask для получения более подробной информации о том, как правильно выполнять сетевые действия.

Вы не должны выполнять какую-то трудоемкую задачу в основном потоке (потоке пользовательского интерфейса), как любая операция в сети, операции ввода-вывода файлов или операции базы данных SQLite. Поэтому для такого рода операций вы должны создать рабочий поток, но проблема в том, что вы не можете напрямую выполнять какую-либо операцию, связанную с пользовательским интерфейсом, из рабочего потока. Для этого вам нужно использовать Handler и передать Message .

Читайте также:  Система операционная система android поддержка android

Чтобы упростить все эти вещи, Android предоставляет различные способы, такие как AsyncTask , AsyncTaskLoader , CursorLoader или IntentService . Поэтому вы можете использовать любой из них в соответствии с вашими требованиями.

Верхний ответ спекта работает отлично.

Если вы пишете AsyncTask inline и не расширяетесь как класс, и, кроме того, если есть необходимость получить ответ из AsyncTask , можно использовать метод get() как AsyncTask ниже.

Хорошей библиотекой является AsyncHTTPClient .

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

Ошибка – предупреждение SDK!

Для меня это было так:

Устройство, на котором я тестировал свое приложение, было 4.1.2, которое представляет собой версию SDK версии 16!

Убедитесь, что целевая версия совпадает с целевой целевой библиотекой Android. Если вы не знаете, что такое ваша целевая библиотека, щелкните правой кнопкой мыши ваш проект -> Путь сборки -> Android , и он должен быть отмечен галочкой.

Кроме того, как указывали другие, укажите правильные разрешения для доступа к Интернету:

Просто для того, чтобы четко сказать что-то:

Основной поток – это в основном поток пользовательского интерфейса.

Поэтому, говоря, что вы не можете выполнять сетевые операции в основном потоке, вы не можете выполнять сетевые операции в потоке пользовательского интерфейса, а это значит, что вы не можете выполнять сетевые операции в *runOnUiThread(new Runnable() < . >* в каком-то другом потоке , или.

(У меня просто был длинный головокружительный момент, пытаясь понять, почему я получал эту ошибку где-то, кроме моего основного потока. Вот почему, этот поток помог, и, надеюсь, этот комментарий поможет кому-то другому.)

Это исключение возникает из-за любой тяжелой задачи, выполняемой в основном потоке, если эта выполняющая задача занимает слишком много времени .

Чтобы этого избежать, мы можем обрабатывать его с помощью потоков или исполнителей

Говоря простыми словами,

НЕ ДЕЛАЙТЕ СЕТЕВЫЕ РАБОТЫ В РЕЖИМЕ UI

Например, если вы выполняете HTTP-запрос, это сетевое действие.

Решение:

  1. Вы должны создать новую тему
  2. Или используйте класс AsyncTask

Путь:

Поместите все свои работы внутри

  1. run() новый поток
  2. Или doInBackground() класса AsyncTask.

Но:

Когда вы получаете что-то из ответа сети и хотите показать его на своем представлении (например, сообщение ответа дисплея в TextView), вам нужно вернуться обратно в поток пользовательского интерфейса .

Если вы этого не сделаете, вы получите ViewRootImpl$CalledFromWrongThreadException .

Как?

  1. При использовании AsyncTask обновите представление из onPostExecute()
  2. Или вызовите runOnUiThread() и обновите представление внутри метода run() .

Хотя выше есть огромный пул решений, никто не упоминается com.koushikdutta.ion : https://github.com/koush/ion

Он также асинхронен и очень прост в использовании:

Это работает. Просто сделал ответ доктора Луиджи немного проще.

Мы также можем использовать RxJava для перемещения сетевых операций в фоновый поток. И это довольно просто.

Вы можете сделать намного больше материалов с RxJava. Вот некоторые ссылки для RxJava. Не стесняйтесь копаться.

Задача RxJava Async в Android

В Android сетевые операции не могут выполняться в основном потоке. Вы можете использовать Thread, AsyncTask (краткосрочные задачи), Service (долгосрочные задачи) для выполнения сетевых операций.

Доступ к сетевым ресурсам из основного (UI) потока вызывает это исключение. Используйте отдельный поток или AsyncTask для доступа к сетевому ресурсу, чтобы избежать этой проблемы.

Вы также можете решить эту проблему, используя Strict Mode, используя приведенный ниже код. Это также альтернатива решению этой проблемы.

Читайте также:  Настройка андроид для начинающих

Но лучше всего использовать AsyncTask.

Я решил эту проблему простым способом …

Я добавил после oncreate StrictMode.enableDefaults(); И решил это.

Используйте Service или AsyncTask чтобы решить эту проблему.

Для получения дополнительной информации проверьте это .

Вам не разрешено выполнять сетевые операции в потоке пользовательского интерфейса на Android. Вам нужно будет использовать класс AsyncTask для выполнения связанных с сетью операций, таких как отправка запроса API, загрузка изображения с URL-адреса и т. Д. И использование методов обратного вызова AsyncTask, вы можете получить результат в onPostExecute menthod, и вы попадете в поток пользовательского интерфейса, и вы Может заполнять пользовательский интерфейс данными из веб-службы или что-то в этом роде.

Пример. Предположим, вы хотите загрузить изображение с URL-адреса: https://www.samplewebsite.com/sampleimage.jpg

Решение с использованием AsyncTask: соответственно.

Примечание. Не забудьте добавить разрешение Интернета в файл манифеста Android. Он будет работать как шарм. 🙂

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

Источник

How to resolve android.os.NetworkOnMainThreadException

Hello friends, I have seen so many new developers facing a specific error android.os.NetworkOnMainThreadException

Why this android crash happened

Main this application crash happened on Android’s Honeycomb(3.0) and above, but it’s works fine on Android’s older versions(2.x). Its because Honeycomb(3.0) and above that version are much stricter about abuse against the UI Thread. For example, when an Android device running 3.0 or above detects a network access on the UI thread, a NetworkOnMainThreadException will be thrown:

Solution of this crash

Creating New Android Project

So let’s start by creating a new android project

1. Create a new project in Eclipse from File ⇒ New ⇒ Android Application Project. I had left my main activity name as MainActivity.java and gave the package name as info.androidstation.networkonmainthread

2. As we are fetching the Data by making HTTP calls, we need to add INTERNET permission in our AndroidManifest.xml file. Open AndroidManifest.xml and add the following permission.

3. We are also checking weather the internet is available or not? We need to add ACCESS_NETWORK_STATE permission in our AndroidManifest.xml file. Open AndroidManifest.xml and add the following permission.

AndroidManifest.xml

4. We are now creating a Utility class called Utility.java. In this class we will check weather internet is available or not? We will also download data from the url using GET method and after that we will read all the downloaded data and convert it into simple string.

Utility.java

5. I am adding a TextView to show the downloaded data. Open the layout file of your main activity and add a TextView element.

activity_main.xml

6. In main activity class (MainActivity.java) I have declared things; one inner class extends AsyncTask and another one is function. Asynctask will call the downloadData function of Utility class in doInBackground override method it’s the separate thread which will not affect to the UI thread. while function directly call the downloadData function from the UI thread so this will throw exception.

MainActivity.java

This Example Output Will look like this:


Hope you all find this tutorial useful. Happy coding. 🙂

Источник

Оцените статью