NetworkOnMainThreadException

Я только что узнал об NetworkOnMainThreadException в официальной документации.

и мне было интересно, бросает ли это эмулятор. Я довольно много тестировал свое приложение, и, насколько я знаю, вся сеть отключена от основного потока (используя Roboguice RoboAsyncTask), но вы никогда не знаете, не сбежал ли он.

Я также использую StrictMode и ничего не видел.

  1. Мой код просто чистый или это не брошено на эмулятор?

  2. Как мы должны подготовиться к тому, что это произойдет в производстве?

  3. Как насчет льготного периода или что-то в этом роде? Или это уже прошло ;-) ??


person Manfred Moser    schedule 01.03.2011    source источник
comment
Это было введено в Android 3.0. Я получил это, когда выполнял сетевую операцию в потоке пользовательского интерфейса, как указано в документации. Я переместил и запустил операцию в отдельном потоке, и она исчезла.   -  person Samuh    schedule 01.03.2011
comment
Вы тоже получаете это в эмуляторе или только с устройства? Без включенного StrictMode?   -  person Manfred Moser    schedule 01.03.2011
comment
У меня получилось на эмуляторе без запуска в StrictMode.   -  person Samuh    schedule 03.03.2011
comment
Нетрудно преднамеренно вызвать это, если вы хотите быть уверены, что это приведет к сообщению об ошибке.   -  person Chris Stratton    schedule 08.08.2011
comment
@Samuh, могу я спросить, какую версию эмулятора Android вы использовали, когда получили исключение NetworkOnMainThreadException? потому что я вообще не мог воспроизвести эту ошибку на эмуляторе. Спасибо!   -  person sammiwei    schedule 25.04.2012
comment
Прочтите эту запись в блоге на NetworkOnMainThreadException для получения дополнительной информации... это очень полезно!   -  person Alex Lockwood    schedule 01.08.2012


Ответы (5)


С сотами вы не можете выполнять сетевые операции в своем основном потоке, как говорится в документации. По этой причине вы должны использовать обработчик или асинтаск. Другого способа сделать это нет.

здесь вы можете найти 2 примера, написанных на турецком языке о работе сети. может они помогут.

person Mustafa Güven    schedule 05.10.2011
comment
Использование Handler не обязательно решает проблему. Поведение Handler по умолчанию также выполняется в основном (UI) потоке. - person David Wasser; 21.10.2016

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

person Manfred Moser    schedule 04.03.2011
comment
В документах говорится следующее: это выдается только для приложений, ориентированных на Honeycomb SDK или выше. Приложениям, ориентированным на более ранние версии SDK, разрешено работать в сети в своих основных потоках цикла событий, но это крайне не рекомендуется. См. документ «Проектирование для гибкости». - person Jeremy Edwards; 05.03.2011
comment
Дополнительную информацию см. в моем блоге на NetworkOnMainThreadException информация. Это объясняет, почему это происходит на Android 3.0 и более поздних версиях. - person Alex Lockwood; 02.08.2012

NetworkOnMainThreadException возникает, когда некоторые сетевые операции выполняются внутри основного метода; Я имею в виду Oncreate(). Вы можете использовать AsyncTask для решения этой проблемы. или вы можете использовать

StrictMode.ThreadPolicy mypolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

внутри onCreate() метода.

person Dharmendra Pratap    schedule 20.05.2016
comment
Это не правильно. Исключение возникает при выполнении сетевого ввода-вывода в основном потоке. Это может произойти в любом методе, а не только в onCreate(). - person David Wasser; 21.10.2016

Если вы используете 3.0, я не могу помочь; Потому что в нем по умолчанию включен строгий режим; Но это выше тату, тогда это может помочь

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

Включите это перед созданием HTTP-соединения; Тогда это работает

person Manoj Kumar    schedule 16.08.2012
comment
старый ответ, но будьте уверены: это неправильный способ! Никогда не делайте никаких сетевых вещей в потоке пользовательского интерфейса. Котенок умрет за каждую миллисекунду задержки, которую вы вызовете этим... - person WarrenFaith; 05.09.2013

Начиная с Honeycomb SDK (3), Google больше не будет разрешать сетевые запросы (HTTP, Socket) и другие связанные операции непосредственно в классе Main Thread, фактически не должен выполнять прямую сетевую операцию в потоке пользовательского интерфейса, блокируя пользовательский интерфейс, взаимодействие с пользователем плохой! Даже если Google не запрещен, при нормальных обстоятельствах мы этого делать не будем ~! Так вот, то есть в версии Honeycomb SDK (3) можно и дальше так делать в Main Thread, больше 3 не получится.

1.используйте Handler

Более трудоемкие операции, связанные с сетью, помещаются в дочерний поток, а затем передаются в основной поток с использованием механизма обмена сообщениями Handler.

public static final String TAG = "NetWorkException";

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_net_work_exception);
    // Opens a child thread, performs network operations, waits for a return result, and uses handler to notify UI
    new Thread(networkTask).start();
}

Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        // get data from msg and notify UI
        Bundle data = msg.getData();
        String val = data.getString("data");
        Log.i(TAG, "the result-->" + val);
    }
};

/**
 * net work task
 */
Runnable networkTask = new Runnable() {

    @Override
    public void run() {
        // do here, the HTTP request. network requests related operations
        Message msg = new Message();
        Bundle data = new Bundle();
        data.putString("data", "request");
        msg.setData(data);
        handler.sendMessage(msg);
    }
};

2.используйте AsyncTask

public static final String TAG = "NetWorkException";
private ImageView mImageView;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_net_work_exception);
    mImageView = findViewById(R.id.image_view);
    new DownImage(mImageView).execute();
}


class DownImage extends AsyncTask<String, Integer, Bitmap> {

    private ImageView imageView;

    public DownImage(ImageView imageView) {
        this.imageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String url = params[0];
        Bitmap bitmap = null;
        try {
            //load image from internet , http request here
            InputStream is = new URL(url).openStream();
            bitmap = BitmapFactory.decodeStream(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        // nodify UI here
        imageView.setImageBitmap(result);
    }
}

3.используйте StrictMode

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}
person KeLiuyue    schedule 22.09.2017