Приложение Android вылетает, как только я загружаю изображение

У меня возникла небольшая проблема с загрузкой изображений из Интернета в мой проект Android. Каждый раз, когда я пытаюсь подключиться к Интернету, мое приложение просто падает.
Да, я добавил разрешение в файл Manifest.xml.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.my.app"
    android:versionCode="1"
    android:versionName="1.0" >

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

LogCat говорит следующее:

06-02 12:15:36.520: E/AndroidRuntime(13947): FATAL EXCEPTION: main
06-02 12:15:36.520: E/AndroidRuntime(13947): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.app/com.my.app.MyAppActivity}: android.os.NetworkOnMainThreadException
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.os.Looper.loop(Looper.java:137)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread.main(ActivityThread.java:4424)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.lang.reflect.Method.invokeNative(Native Method)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.lang.reflect.Method.invoke(Method.java:511)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at dalvik.system.NativeStart.main(Native Method)
06-02 12:15:36.520: E/AndroidRuntime(13947): Caused by: android.os.NetworkOnMainThreadException
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.net.InetAddress.getAllByName(InetAddress.java:220)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpConnection.<init>(HttpConnection.java:71)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:351)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:86)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:308)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpEngine.connect(HttpEngine.java:303)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.net.URLConnection.getContent(URLConnection.java:194)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at java.net.URL.getContent(URL.java:447)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at com.my.app.MyAppActivity.onCreate(MyAppActivity.java:25)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.Activity.performCreate(Activity.java:4465)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
06-02 12:15:36.520: E/AndroidRuntime(13947):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
06-02 12:15:36.520: E/AndroidRuntime(13947):    ... 11 more

Потратил почти час, пытаясь понять, в чем проблема....


person phil    schedule 02.06.2012    source источник
comment
stackoverflow.com/questions/6343166/   -  person Akram    schedule 02.06.2012


Ответы (6)


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

см. этот пример

person Samir Mangroliya    schedule 02.06.2012

Если вы используете метод для загрузки изображения в onCreate(), он будет вести себя как синхронная операция — то есть, он не вернет управление, пока изображение не будет загружено — его вызов напрямую приведет к зависанию пользовательского интерфейса. ваших действий. Это запрещено в Android 3.0 и более поздних версиях; весь синхронный код должен быть заключен в класс AsyncTask. Использование AsyncTask позволяет выполнять фоновые задачи в отдельном потоке, а затем возвращать результат в поток пользовательского интерфейса. Таким образом, вы можете выполнять фоновые операции без необходимости решать сложные проблемы с потоками.

Чтобы вызвать метод DownloadImage() асинхронно, вам нужно поместить код в подкласс класса AsyncTask, как показано здесь:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    protected Bitmap doInBackground(String... urls) {
        return DownloadImage(urls[0]);
    }
    protected void onPostExecute(Bitmap result) {
        ImageView img = (ImageView) findViewById(R.id.img);
        img.setImageBitmap(result);
    }
}
person vanguard69    schedule 16.01.2015

Каждый контент должен быть загружен в отдельный поток... Вы можете использовать AsyncTask, Thread...

person ChristopheCVB    schedule 02.06.2012

Для этого вы должны использовать асинхронную задачу, это надежная защита, поэтому ваш основной поток (поток пользовательского интерфейса) не зависает. Они добавили это в 3.0 или 3.1, просто откопайте старый пост для примера.

HTTP POST-запрос ANDROID 4 (работает в версии 2.3) ?

Было бы очень плохой практикой идти против Android и делать сеть в основном потоке. Они сделали это по какой-то причине, скорее всего, так и будет, если вы этого не сделаете.

person FabianCook    schedule 02.06.2012

Хорошей практикой при создании адаптивных приложений является убедиться, что ваш основной поток пользовательского интерфейса выполняет минимальный объем работы. Любая потенциально длительная задача, которая может привести к зависанию вашего приложения, должна обрабатываться в другом потоке (фоновом потоке). когда вы выполняете длительную операцию в своем основном потоке, вы теряете отзывчивость своего приложения для Android, и если вы используете такие задачи с сетевыми операциями, вы получите android.os.NetworkOnMainThreadException исключение.

Типичными примерами таких задач являются сетевые операции, связанные с непредсказуемыми задержками. Пользователи будут терпеть некоторые паузы, особенно если вы сообщаете, что что-то происходит, но зависшее приложение не дает им никакой информации.

В этой статье мы создадим простое изображение загрузчик, который иллюстрирует этот шаблон

вы узнаете разницу между различными подходами и, наконец, вы должны помнить, как правильно выполнять такие операции!

Вы также можете увидеть этот имитирующий поток SO , связанный с ленивой загрузкой

person K_Anas    schedule 02.06.2012

Пожалуйста, обратитесь к этому ответу

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

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

Дополнительные сведения см. на сайте разработчиков Android.

person ZAQ    schedule 02.06.2012