'Android.os.NetworkOnMainThreadException' nasıl düzeltilir?


2394

RssReader için Android projemi çalıştırırken bir hata aldım.

Kod:

URL url = new URL(urlToRssFeed);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader xmlreader = parser.getXMLReader();
RssHandler theRSSHandler = new RssHandler();
xmlreader.setContentHandler(theRSSHandler);
InputSource is = new InputSource(url.openStream());
xmlreader.parse(is);
return theRSSHandler.getFeed();

Ve aşağıdaki hatayı gösterir:

android.os.NetworkOnMainThreadException

Bu sorunu nasıl düzeltebilirim?


131
Daha fazla bilgi için NetworkOnMainThreadException üzerindeki bu blog gönderisini okuyun . Bunun Android 3.0 ve üstü sürümlerde neden oluştuğunu açıklar.
Adrian Monk

6
Rite yolda olmak ilk android Ağ İstekleri hakkında okumak sonra "Volley" çalışma tavsiye ederim.
Anuj Sharma

3
Bu sorunu çözen birçok alternatif kitaplık var. Birçoğu bu sayfanın altında listelenmiştir . Daha fazlasına sahipseniz, onları
alırız

İnternet faaliyetlerini ana (UI) iş parçacığından ayrı bir iş parçacığında çalıştırmanız gerekiyor
Naveed Ahmad

"Android'in önceki sürümlerindeki bir hata nedeniyle, sistem ana iş parçacığında bir TCP soketine yazma işlemini katı mod ihlali olarak işaretlemedi. Android 7.0 bu hatayı düzeltir. Bu davranışı sergileyen uygulamalar artık bir android.os atıyor. NetworkOnMainThreadException." - Yani bazılarımız yakın zamana kadar buna çarpmadık! developer.android.com/about/versions/nougat/…
Jay

Yanıtlar:


2547

Bir uygulama ana iş parçacığında bir ağ işlemi gerçekleştirmeye çalıştığında bu özel durum atılır. Kodunuzu şurada çalıştırın AsyncTask:

class RetrieveFeedTask extends AsyncTask<String, Void, RSSFeed> {

    private Exception exception;

    protected RSSFeed doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            XMLReader xmlreader = parser.getXMLReader();
            RssHandler theRSSHandler = new RssHandler();
            xmlreader.setContentHandler(theRSSHandler);
            InputSource is = new InputSource(url.openStream());
            xmlreader.parse(is);

            return theRSSHandler.getFeed();
        } catch (Exception e) {
            this.exception = e;

            return null;
        } finally {
            is.close();
        }
    }

    protected void onPostExecute(RSSFeed feed) {
        // TODO: check this.exception
        // TODO: do something with the feed
    }
}

Görev nasıl yürütülür:

Gelen MainActivity.javadosyanın Eğer içinde bu satırı ekleyebilirsiniz oncreate()yöntemle

new RetrieveFeedTask().execute(urlToRssFeed);

Bunu AndroidManifest.xmldosyaya eklemeyi unutmayın :

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

37
Yukarıdaki kod snippet'inin bir alt sınıf (iç sınıf), tercihen özel olması gerektiğini belirtmek gerekir. Bu şekilde AsyncTask bittiğinde, yine de sınıfınızın iç kısımlarını manipüle edebilirsiniz.
dyslexicanaboko

4
Aslında u yukarıda belirtilen aynı şeyi yaptım ama bu hatayla karşı karşıya m java.lang.RuntimeException: Looper.prepare () çağırmamış iş parçacığı içinde işleyici oluşturulamıyor
Dhruv Tyagi

68
Bu tam olarak yanlış cevap. Bu insanların kodu her zaman rastlamak ve her zaman düzeltmek zorunda sinir bozucu. AsyncTask ağ etkinliği için kullanılmamalıdır, çünkü etkinliğe bağlıdır, ancak etkinlik yaşam döngüsüne bağlı değildir. Bu görev çalışırken cihazı döndürmek bir istisnaya neden olur ve uygulamanızı kilitler. Bunun yerine sqlite veritabanında veri bırakan bir IntentService kullanın.
Brill Pappin

5
Dikkat, AsyncTask genellikle olmaması gereken her etkinlik ağı işlemi için kullanılır. yaşam döngüsü etkinlikle senkronize değildir. Veri almak için görünümün arkasında bir IntentService ve veritabanı kullanmalısınız.
Brill Pappin

1
@BrillPappin, FWIW, bu Android Geliştirici KılavuzuAsyncTask bir yapılandırma değişikliğini kullanır ve ilgilenir.
HeyJude

677

Neredeyse her zaman bir iş parçacığında veya eşzamansız görev olarak ağ işlemlerini çalıştırmalısınız.

Ama olan bu kısıtlamayı kaldırmak ve sonuçlarını kabul etmeye istekli olup olmadığını, varsayılan davranışı geçersiz kılmak mümkün.

Ekle:

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

StrictMode.setThreadPolicy(policy); 

Sınıfında,

ve

Bu izni android manifest.xml dosyasında EKLE:    

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

Sonuçlar:

Uygulamanız (sivilceli internet bağlantısı alanlarında) yanıt vermeyecek ve kilitlenecek, kullanıcı yavaşlığı algılayacak ve bir zorla öldürme yapmak zorunda kalacak ve etkinlik yöneticisinin uygulamanızı öldürmesini ve kullanıcıya uygulamanın durduğunu söylemesini riske atıyorsunuz.

Android'in yanıt vermek üzere tasarlanması için iyi programlama uygulamalarıyla ilgili bazı ipuçları vardır: http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html


456
Bu çok kötü bir fikir. çözüm, ana iş parçacığında ağ IO'sundan kaçınmaktır (kabul edilen yanıtın gösterdiği gibi).
MByD

74
Bununla sadece gerçek probleminizi gizlersiniz.
Alex

28
@TwistedUmbrella AsyncTask bir kod sayfası eklemez, 6 satır ekler (sınıf bildirimi, geçersiz kılma açıklaması, doInBackgroundbildirim, 2 kapanış köşeli ayraç ve çağrılması execute()). Öte yandan, bahsettiğiniz gibi bir siteden tek bir getirme bile kullanıcı arayüzünün duyarlılığında önemli bir gecikme getirir. Tembel olma.
Zoltán

19
Ben sadece bir şey uygun AsyncTask uygulamadan önce işe yarayıp yaramadığını görmek için örnek bir kod yığını çalıştırmak istiyorsanız bu mükemmel bir çözüm olduğunu düşünüyorum. Bu yüzden bu cevabı iptal ettim, ancak diğerlerinin söylediği gibi, bu bir üretim uygulamasında değil, sadece bir dev testi için hızlı bir çözüm olarak yapılmalıdır.
hooked82

94
Upvoted. Bu cevap doğrudur ve ne saf ne de aptal olan, ancak sadece bir SYNCHRONOUS (yani: bu uygulamayı engellemelidir ) çağrısı gerektiren birçok programcı için tam olarak ihtiyaç duyulan şey budur. Android'in varsayılan olarak istisnayı attığı için çok mutluyum (IMHO yapmak çok "yararlı" bir şey!) - Ama "teşekkürler" demekle aynı derecede mutluyum, ama - aslında istediğim şey bu ve geçersiz kılmak o.
Adam

428

Bu sorunu yeni kullanarak çözdüm Thread.

Thread thread = new Thread(new Runnable() {

    @Override
    public void run() {
        try  {
            //Your code goes here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

thread.start(); 

7
Her ağ işlemi gerçekleştirmek istediğinizde yeni bir iş parçacığı oluşturmak yerine, tek bir iş parçacığı yürütme hizmetini de kullanabilirsiniz.
Alex Lockwood

66
Basit ama tehlikeli. Anonim Runnable, iş parçacığı tamamlanıncaya kadar çöp toplanmasını önleyerek çevreleyen sınıfa (örn., Etkinliğiniz veya Parçanız) örtük bir referansa sahiptir. En azından önceliği Process.BACKGROUND olarak ayarlamanız gerekir, aksi takdirde bu iş parçacığı, yaşam döngüsü yöntemleri ve ui kare hızlarına (koreograftan gelen günlük uyarılarına dikkat edin) karşılık olarak ana / ui iş parçacığıyla aynı önceliğe sahip olarak çalışır.
Stevie

1
@Stevie önceliği nasıl ayarlamalı? ne runnble ne de execiverService böyle bir ayarlayıcı yönteme sahip değil
JK

1
@JK ExecutorService'inize özel bir ThreadFactory sağlayın ve geri dönmeden önce thread.setPriority öğesini çağırın.
Stevie

1
"Threads'ı doğrudan Android'de kullanmak cesaretini kırıyor. Çözdüğünden daha fazla soruna neden oluyor" Bunun üzerinde durmak ister misiniz? Aslında AsyncTask bunun için tam olarak kullanımdan kaldırılıyor ... techyourchance.com/asynctask-deprecated
Fran Marzoa

170

Kabul edilen cevabın bazı önemli yanları vardır. Ne yaptığınızı gerçekten bilmiyorsanız , ağ için AsyncTask'i kullanmanız önerilmez . Aşağı taraflardan bazıları şunlardır:

  • Statik olmayan iç sınıflar olarak oluşturulan AsyncTask, çevreleyen Activity nesnesine, içeriğine ve bu etkinlik tarafından oluşturulan tüm View hiyerarşisine örtük bir referansa sahiptir. Bu referans, AsyncTask'ın arka plan çalışması tamamlanıncaya kadar Etkinliğin çöp toplanmasını önler. Kullanıcının bağlantısı yavaşsa ve / veya indirme büyükse, bu kısa süreli bellek sızıntıları sorun yaratabilir - örneğin, yönlendirme birkaç kez değişirse (ve yürütme görevlerini iptal etmezseniz) veya kullanıcı Etkinlikten uzaklaşır.
  • AsyncTask, yürüttüğü platforma bağlı olarak farklı yürütme özelliklerine sahiptir: API seviye 4'ten önce AsyncTasks tek bir arka plan iş parçacığında seri olarak yürütür; API seviye 4'ten API seviye 10'a kadar, AsyncTasks 128 iş parçacığına kadar bir havuzda yürütülür; API seviye 11'den itibaren AsyncTask tek bir arka plan iş parçacığında seri olarak yürütür (aşırı yüklenmiş executeOnExecutoryöntemi kullanmazsanız ve alternatif bir yürütücü sağlamazsanız). ICS'de seri olarak çalıştırılırken iyi çalışan kod, Gingerbread üzerinde eşzamanlı olarak yürütüldüğünde bozulabilir, örneğin yanlışlıkla yürütme sırası bağımlılıklarınız varsa.

Kısa süreli bellek sızıntılarından kaçınmak, tüm platformlarda iyi tanımlanmış yürütme özelliklerine sahip olmak ve gerçekten sağlam ağ kullanımı oluşturmak için bir tabana sahip olmak istiyorsanız, aşağıdakileri dikkate almak isteyebilirsiniz:

  1. Sizin için güzel bir iş yapan bir kütüphane kullanmak - bu sorudaki ağ kütüphanelerinin güzel bir karşılaştırması var veya
  2. Etkinliğin yöntemi aracılığıyla sonucu döndürmek için a Serviceveya IntentServicebunun yerine, belki de a ile .PendingIntentonActivityResult

IntentService yaklaşımı

Aşağı taraf:

  • AsyncTaskDüşündüğünüz kadar olmasa da, daha fazla kod ve karmaşıklık
  • İstekleri sıralar ve tek bir arka plan iş parçacığında çalıştırır . Kolayca değiştirerek bu kontrol edebilirsiniz IntentServiceeşdeğer ile Servicebelki gibi, uygulama bu bir .
  • Um, şu anda başkalarını düşünemiyorum aslında

Yukarı-taraf:

  • Kısa süreli bellek sızıntısı sorununu önler
  • Ağ operasyonları uçuştayken etkinliğiniz yeniden başlatılırsa indirme işlemi yine de onActivityResultyöntemi aracılığıyla alınabilir
  • Güçlü ağ kodu oluşturmak ve yeniden kullanmak için AsyncTask'tan daha iyi bir platform. Örnek: Önemli bir yükleme yapmak gerekiyorsa, onu yapabileceği AsyncTaskbir in Activity, ancak kullanıcı bir telefon görüşmesi almak için uygulamadan çıkış bağlam anahtarları, sistem olabilir yükleme tamamlamadan önce uygulama kapatılacaktır. Öyle az olasılıkla aktif olan bir uygulamayı öldürmek için Service.
  • Kendi eşzamanlı sürümünüzü IntentService(yukarıda bağlantı verdiğim gibi) kullanıyorsanız, eşzamanlılık seviyesini Executor.

Uygulama özeti

IntentServiceTek bir arka plan iş parçacığında indirmeleri oldukça kolay bir şekilde gerçekleştirmek için bir uygulayabilirsiniz.

1. Adım: IntentServiceİndirme işlemini gerçekleştirmek için bir oluşturun . Ekstralar aracılığıyla neyi indireceğinizi söyleyebilir ve sonucu aşağıdakilere döndürmek için kullanmak için Intentbir iletebilirsiniz :PendingIntentActivity

import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class DownloadIntentService extends IntentService {

    private static final String TAG = DownloadIntentService.class.getSimpleName();

    public static final String PENDING_RESULT_EXTRA = "pending_result";
    public static final String URL_EXTRA = "url";
    public static final String RSS_RESULT_EXTRA = "url";

    public static final int RESULT_CODE = 0;
    public static final int INVALID_URL_CODE = 1;
    public static final int ERROR_CODE = 2;

    private IllustrativeRSSParser parser;

    public DownloadIntentService() {
        super(TAG);

        // make one and re-use, in the case where more than one intent is queued
        parser = new IllustrativeRSSParser();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
        InputStream in = null;
        try {
            try {
                URL url = new URL(intent.getStringExtra(URL_EXTRA));
                IllustrativeRSS rss = parser.parse(in = url.openStream());

                Intent result = new Intent();
                result.putExtra(RSS_RESULT_EXTRA, rss);

                reply.send(this, RESULT_CODE, result);
            } catch (MalformedURLException exc) {
                reply.send(INVALID_URL_CODE);
            } catch (Exception exc) {
                // could do better by treating the different sax/xml exceptions individually
                reply.send(ERROR_CODE);
            }
        } catch (PendingIntent.CanceledException exc) {
            Log.i(TAG, "reply cancelled", exc);
        }
    }
}

2. Adım: Hizmeti manifest'e kaydedin:

<service
        android:name=".DownloadIntentService"
        android:exported="false"/>

Adım 3: Hizmetin sonucu döndürmek için kullanacağı bir PendingResult nesnesini ileterek hizmeti Etkinlik'ten çağırın:

PendingIntent pendingResult = createPendingResult(
    RSS_DOWNLOAD_REQUEST_CODE, new Intent(), 0);
Intent intent = new Intent(getApplicationContext(), DownloadIntentService.class);
intent.putExtra(DownloadIntentService.URL_EXTRA, URL);
intent.putExtra(DownloadIntentService.PENDING_RESULT_EXTRA, pendingResult);
startService(intent);

Adım 4: Sonucu onActivityResult içinde tutun:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == RSS_DOWNLOAD_REQUEST_CODE) {
        switch (resultCode) {
            case DownloadIntentService.INVALID_URL_CODE:
                handleInvalidURL();
                break;
            case DownloadIntentService.ERROR_CODE:
                handleError(data);
                break;
            case DownloadIntentService.RESULT_CODE:
                handleRSS(data);
                break;
        }
        handleRSS(data);
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Tam çalışan bir Android-Studio / Gradle projesi içeren bir Github projesi burada mevcuttur .


IntentService bunu yapmanın doğru yoludur, kökten sökülmez çünkü AsyncTask tam olarak bunu yapmamanın yoludur.
Brill Pappin

3
@BrillPappin AsyncTask'in dezavantajlarını vurgulamak için neredeyse tamamen katılıyorum ve yeniden ifade edildim. (Hala olduğunu düşünüyorum çok küçük o - Eğer gerçekten ne yaptığınızı biliyorsanız - vaka sayısı olabilir Tamam AsyncTask kullanmak olabilir, ancak kabul cevap herhangi bir sakınca işaret ve iyiliği için yol çok popüler değil Android).
Stevie

1
Gerçekten ihtiyacınız var IllustrativeRSSmı? RSS işleriyle çalışmıyorsanız ne olacak?
Cullub

Bence Google, berdonu programcıların yanına koymak yerine, çöp toplama uygulamalarının kötü uygulamasını değiştirmelidir. Bu OS'nin sorumluluğundadır. Bir programcı, Android uygulamasındaki temel sorun nedeniyle işi yapmak için IntentService veya Service kullanıyorsa, birkaç yıl sonra Google IntentService'in de kötü bir uygulama olduğunu ve başka bir şey önerdiğini söyleyecektir. Ve bu hikaye devam ediyor ... Bu yüzden Google geliştiricileri, programcıları değil Android kötü bellek yönetimini çözmelidir.
saeed khalafinejad

Ben sadece şunu söyleyeceğim: Bu cevap, projeyi paylaşmanın daha iyi bir alternatif olmaktan çok bir yolu gibi görünüyor AsyncTask. Hata, geliştiricilerin kullanıcı arayüzünü geciktirmelerini durdurmak, onları bir dizi amaç / hizmetle güvenliği riske atmak zorunda bırakmamak anlamına geliyordu.
Terk Edilmiş Sepet

144

Honeycomb üzerindeki UI iş parçacığında ağ G / Ç gerçekleştiremezsiniz . Teknik olarak ise Android'in eski sürümlerinde mümkün, ama buna uygulama yanıt vermemesine neden olur ve kötü huylu olma için uygulamanızı öldürme OS neden olabilir olarak gerçekten kötü bir fikirdir. Ağ işleminizi bir arka plan iş parçacığında gerçekleştirmek için bir arka plan işlemi çalıştırmanız veya AsyncTask kullanmanız gerekir.

Android geliştirici sitesinde Ağrısız Diş Açma ile ilgili bir makale var, bu da iyi bir tanıtımdır ve size burada gerçekçi olarak sağlanabilecek olandan çok daha iyi bir cevap derinliği sağlayacaktır.


76
  1. StrictMode kullanmayın (yalnızca hata ayıklama modunda)
  2. SDK sürümünü değiştirme
  3. Ayrı bir iplik kullanmayın

Service veya AsyncTask kullanın

Ayrıca bkz. Yığın Taşması sorusu:

android.os.NetworkOnMainThreadException Android'den bir e-posta gönderme


8
Belki de bir Hizmet kullanırsanız, yine de ayrı bir iş parçacığı oluşturmanız gereken noktayı vurgulamaya değer - Ana iş parçacığında hizmet geri çağrıları çalışır. Öte yandan bir IntentService, onHandleIntent yöntemini bir arka plan iş parçacığında çalıştırır.
Stevie

uzun süreli operasyonlar için AsyncTask kullanmamalısınız! Yönergeler en fazla 2 ila 3 saniye belirtir.
Dage

76

Başka bir iş parçacığında ağ eylemlerini gerçekleştirme

Örneğin:

new Thread(new Runnable(){
    @Override
    public void run() {
        // Do network action in this function
    }
}).start();

Ve bunu AndroidManifest.xml dosyasına ekleyin

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

5
Ancak, UI iş parçacığında bir sonraki görevleri yerine getirebilmemiz için iş parçacığının bu işin bittiğini nasıl öğrenebiliriz? AsyncTask bunu yapmak için kolaylık sağlar. Aynı işlemi çalıştırılabilir dişler kullanarak yapmanın bir yolu var mı?
Piyush Soni

3
Kodunuzu adım adım işleyecek, bu nedenle kodun sonunda bitmiş, işleyiciyi UI iş parçacığına geri kullanmanız gerekiyor
henry4343

1
Çalışan iş parçacığında yürütüldüğü için zaman uyumsuz görev veya amaç hizmetini kullanabilirsiniz.
Chetan Chaudhari

64

Sıkı modu aşağıdaki kodu kullanarak devre dışı bırakırsınız:

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

Bu önerilmez : AsyncTaskarayüzü kullanın .

Her iki yöntem için de tam kod


2
Evet ANR hatası gelirdi. Uygulama 5 saniye içinde yanıt vermiyor demektir.
Muhammed Mübarek

11
Bu gerçekten kötü bir cevap. İş parçacığının ilkesini değiştirmemeli, daha iyi kod yazmalısınız: ana iş parçacığında ağ işlemleri yapmayın!
shkschneider

@Sandeep Siz ve diğer izleyiciler de bunu okumalısınız. stackoverflow.com/a/18335031/3470479
Prakhar1001

54

Ağ tabanlı işlemler ana iş parçacığında çalıştırılamaz. Bir alt iş parçacığında tüm ağ tabanlı görevleri çalıştırmanız veya AsyncTask'i uygulamanız gerekir.

Alt iş parçacığında bir görevi şu şekilde çalıştırırsınız:

new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            // Your implementation goes here
        } 
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}).start();

Anonim Runnable en iyi yol DEĞİLDİR, çünkü kapalı sınıf için örtük bir referansa sahiptir ve iş parçacığı tamamlanıncaya kadar GC düzenlenmesi önlenir! Ayrıca, bu iş parçacığı, yaşam döngüsü yöntemleri ve kullanıcı arabirimi kare hızlarına göre ana / ABD iş parçacığıyla aynı Öncelikte çalışacaktır!
Yousha Aleayoub

49

Kodunuzu içine yerleştirin:

new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            // Your implementation
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}).start();

Veya:

class DemoTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... arg0) {
        //Your implementation
    }

    protected void onPostExecute(Void result) {
        // TODO: do something with the feed
    }
}

İkincisi 11 daha yukarıda API için ilk daha iyi olacak
Rohit'e Goswami

46

Bu, Android 3.0 ve sonraki sürümlerde gerçekleşir. Android 3.0 ve üstü sürümlerde, ağ işlemlerini (Internet'e erişen işlevler) ana iş parçacığı / UI iş parçacığında (oluşturma sırasında ve etkinlikte devam etme yöntemlerinde ortaya çıkan) kullanmasını kısıtladılar.

Bu, ağ işlemleri için ayrı iş parçacıklarının kullanılmasını teşvik etmektir. Ağ etkinliklerini doğru şekilde gerçekleştirme hakkında daha fazla bilgi için AsyncTask'a bakın .


46

Android Ek Açıklamalarını kullanmak bir seçenektir. Bir arka plan iş parçacığında herhangi bir yöntemi çalıştırmanıza izin verir:

// normal method
private void normal() {
    doSomething(); // do something in background
}

@Background
protected void doSomething() 
    // run your networking code here
}

Basitlik ve okunabilirliğin faydalarını sağlamasına rağmen, dezavantajları olduğunu unutmayın.


6
@Gavriel, bir yöntem, etkinlik, fragman, singleton vb. Ayrıca kitaplıktaki hatalar nedeniyle bazı sorunlar olabilir. Hata ayıklama ve hata bulma daha zor hale gelir.
Oleksiy

43

Hata, ana iş parçacığında uzun süre çalışan işlemlerin yürütülmesi nedeniyle, AsynTask veya İş parçacığı kullanarak sorunu kolayca düzeltebilirsiniz . Daha iyi işlem için bu kütüphaneyi AsyncHTTPClient'e göz atabilirsiniz .

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {

    @Override
    public void onStart() {
        // Called before a request is started
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // Called when response HTTP status is "200 OK"
    }

    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // Called when response HTTP status is "4XX" (for example, 401, 403, 404)
    }

    @Override
    public void onRetry(int retryNo) {
        // Called when request is retried
    }
});

42

Ana iş parçacığında (UI iş parçacığı) herhangi bir ağ işlemi, dosya G / Ç veya SQLite veritabanı işlemleri gibi zaman alıcı bir işlem yapmamalısınız. Bu tür bir işlem için, bir işçi iş parçacığı oluşturmanız gerekir, ancak sorun, işçi iş parçacığından kullanıcı arabirimi ile ilgili herhangi bir işlemi doğrudan gerçekleştirememenizdir. Bunun için, kullanmak Handlerve geçmek zorunda Message.

Tüm bunları basitleştirmek için, Android çeşitli yolları gibi sağlar AsyncTask, AsyncTaskLoader, CursorLoaderveya IntentService. Böylece bunlardan herhangi birini gereksinimlerinize göre kullanabilirsiniz.


40

Spektom'un en iyi cevabı mükemmel çalışıyor.

AsyncTaskSatır içi yazıyorsanız ve bir sınıf olarak uzanmıyorsanız ve bunun üzerine, bir yanıt almanız gerekiyorsa AsyncTask, get()yöntem aşağıdaki gibi kullanılabilir.

RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();

(Örneğinden.)


5
kullanmak get()kötü bir fikir ... AsyncTask'ı tekrar "senkronize ediyor"
Selvin

Bundan daha iyi bir çıkış yolu var mı? @Selvin
sivag1

2
Sonuç hakkında ana iş parçacığı bilgi olabilir.Örneğin, sonuç da dahil olmak üzere ana iş parçacığına bir yayın gönderin.
Chine Gary

32

Bu yalnızca Honeycomb SDK veya daha üstünü hedefleyen uygulamalar için atılır . Daha önceki SDK sürümlerini hedefleyen uygulamaların ana olay döngüsü iş parçacıkları üzerinde ağ oluşturmalarına izin verilir.

Hata SDK uyarısıdır!


28

Benim için şöyle oldu:

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="10" />

Uygulamamı test ettiğim cihaz SDK Sürüm 16 olan 4.1.2 idi!

Hedef sürümün Android Hedef Kitaplığınızla aynı olduğundan emin olun. Hedef kütüphanenizin ne olduğundan emin değilseniz, Project -> Oluşturma Yolu -> Android öğelerine sağ tıklayın ve işaretlenen kitap olmalıdır.

Ayrıca, diğerlerinin de belirttiği gibi, İnternet'e erişmek için doğru izinleri ekleyin:

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

11
Size burada ne yaptığınızı açıklayayım: size NetworkOnMainThreadExceptionsöyleyen Guardian: kendi ayağınıza ateş etmeyin ... çözümünüz: Guardian olmadığında geçmişe geri dönelim - şimdi benim serbestçe ayak
Selvin

1
Bu yaklaşımı da aldım ve hiç problem yaşamadım. Koruyucu bazen çok telaşlı.
FractalBob

25

Bunu Faaliyetinizde kullanın

    btnsub.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Thread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub

                    //Initialize soap request + add parameters
                    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);

                    //Use this to add parameters
                    request.addProperty("pincode", txtpincode.getText().toString());
                    request.addProperty("bg", bloodgroup.getSelectedItem().toString());

                    //Declare the version of the SOAP request
                    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

                    envelope.setOutputSoapObject(request);
                    envelope.dotNet = true;

                    try {
                        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

                        //this is the actual part that will call the webservice
                        androidHttpTransport.call(SOAP_ACTION1, envelope);

                        // Get the SoapResult from the envelope body.
                        SoapObject result = (SoapObject) envelope.getResponse();
                        Log.e("result data", "data" + result);
                        SoapObject root = (SoapObject) result.getProperty(0);
                        // SoapObject s_deals = (SoapObject) root.getProperty(0);
                        // SoapObject s_deals_1 = (SoapObject) s_deals.getProperty(0);
                        //

                        System.out.println("********Count : " + root.getPropertyCount());

                        value = new ArrayList<Detailinfo>();

                        for (int i = 0; i < root.getPropertyCount(); i++) {
                            SoapObject s_deals = (SoapObject) root.getProperty(i);
                            Detailinfo info = new Detailinfo();

                            info.setFirstName(s_deals.getProperty("Firstname").toString());
                            info.setLastName(s_deals.getProperty("Lastname").toString());
                            info.setDOB(s_deals.getProperty("DOB").toString());
                            info.setGender(s_deals.getProperty("Gender").toString());
                            info.setAddress(s_deals.getProperty("Address").toString());
                            info.setCity(s_deals.getProperty("City").toString());
                            info.setState(s_deals.getProperty("State").toString());
                            info.setPinecode(s_deals.getProperty("Pinecode").toString());
                            info.setMobile(s_deals.getProperty("Mobile").toString());
                            info.setEmail(s_deals.getProperty("Email").toString());
                            info.setBloodgroup(s_deals.getProperty("Bloodgroup").toString());
                            info.setAdddate(s_deals.getProperty("Adddate").toString());
                            info.setWaight(s_deals.getProperty("waight").toString());
                            value.add(info);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    Intent intent = new Intent(getApplicationContext(), ComposeMail.class);
                    //intent.putParcelableArrayListExtra("valuesList", value);

                    startActivity(intent);
                }
            }).start();
        }
    });

23

Sadece bir şeyi açıkça söylemek için:

Ana iş parçacığı temelde UI iş parçacığıdır.

Eğer gelir UI iş parçacığı, operasyonlara ağ uğraşma ana iş parçacığı aracı operasyonları ağ yapmak olamayacağını söyleyerek Yani bir faaliyet ağ uğraşma *runOnUiThread(new Runnable() { ... }*bloğu ya da başka iş parçacığı içine.

(Neden sadece ana iş parçacığı dışında bir yerde bu hatayı alıyorum anlamaya çalışırken uzun bir kafa çizik an vardı. Bu yüzden; bu iş parçacığı yardımcı oldu; ve umarım bu yorum başka birine yardımcı olacaktır.)


22

Bu özel durum, gerçekleştirme görevi çok fazla zaman alıyorsa ana iş parçacığında gerçekleştirilen ağır görev nedeniyle oluşur .

Bunu önlemek için, biz kullanarak işleyebilir konuları veya bir uygulayıcı

Executors.newSingleThreadExecutor().submit(new Runnable() {
    @Override
    public void run() {
        // You can perform your task here.
    }
});

18

Bu soruda zaten birçok harika cevap var, ancak bu cevaplar gönderildiği için birçok harika kütüphane ortaya çıktı. Bu bir tür acemi rehber olarak tasarlanmıştır.

Ağ işlemlerini gerçekleştirmek için birkaç kullanım durumunu ve her biri için bir veya iki çözümü ele alacağım .

HTTP üzerinden ReST

Genellikle Json, XML veya başka bir şey olabilir

Tam API Erişimi

Kullanıcıların hisse senedi fiyatlarını, faiz oranlarını ve cari döviz kurlarını takip etmesini sağlayan bir uygulama yazdığınızı varsayalım. Şuna benzer bir Json API'sı bulursunuz:

http://api.example.com/stocks                       //ResponseWrapper<String> object containing a list of Srings with ticker symbols
http://api.example.com/stocks/$symbol               //Stock object
http://api.example.com/stocks/$symbol/prices        //PriceHistory<Stock> object
http://api.example.com/currencies                   //ResponseWrapper<String> object containing a list of currency abbreviation
http://api.example.com/currencies/$currency         //Currency object
http://api.example.com/currencies/$id1/values/$id2  //PriceHistory<Currency> object comparing the prices of the first currency (id1) to the second (id2)

Square'den sonradan yükseltme

Bu, birden fazla uç noktaya sahip bir API için mükemmel bir seçimdir ve iyon veya Volley gibi diğer kütüphanelerde olduğu gibi bunları ayrı ayrı kodlamak yerine ReST uç noktalarını bildirmenizi sağlar. (web sitesi: http://square.github.io/retrofit/ )

Finans API'sı ile nasıl kullanıyorsunuz?

build.gradle

Bu satırları Modül düzeyi buid.gradle'a ekleyin:

implementation 'com.squareup.retrofit2:retrofit:2.3.0' //retrofit library, current as of September 21, 2017
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' //gson serialization and deserialization support for retrofit, version must match retrofit version

FinancesApi.java

public interface FinancesApi {
    @GET("stocks")
    Call<ResponseWrapper<String>> listStocks();
    @GET("stocks/{symbol}")
    Call<Stock> getStock(@Path("symbol")String tickerSymbol);
    @GET("stocks/{symbol}/prices")
    Call<PriceHistory<Stock>> getPriceHistory(@Path("symbol")String tickerSymbol);

    @GET("currencies")
    Call<ResponseWrapper<String>> listCurrencies();
    @GET("currencies/{symbol}")
    Call<Currency> getCurrency(@Path("symbol")String currencySymbol);
    @GET("currencies/{symbol}/values/{compare_symbol}")
    Call<PriceHistory<Currency>> getComparativeHistory(@Path("symbol")String currency, @Path("compare_symbol")String currencyToPriceAgainst);
}

FinancesApiBuilder

public class FinancesApiBuilder {
    public static FinancesApi build(String baseUrl){
        return new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(FinancesApi.class);
    }
}

Parça pasajı

FinancesApi api = FinancesApiBuilder.build("http://api.example.com/"); //trailing '/' required for predictable behavior
api.getStock("INTC").enqueue(new Callback<Stock>(){
    @Override
    public void onResponse(Call<Stock> stockCall, Response<Stock> stockResponse){
        Stock stock = stockCall.body();
        //do something with the stock
    }
    @Override
    public void onResponse(Call<Stock> stockCall, Throwable t){
        //something bad happened
    }
}

API'nizin gönderilmesi için bir API Anahtarı veya kullanıcı belirteci gibi başka bir başlık vb. Gerekiyorsa, Retrofit bunu kolaylaştırır (ayrıntılar için bu müthiş cevaba bakın: https://stackoverflow.com/a/42899766/1024412 ).

Bir kerelik ReST API erişimi

Kullanıcıların GPS konumunu arayan ve o bölgedeki mevcut sıcaklığı kontrol eden ve onlara havayı anlatan bir "hava durumu hava durumu" uygulaması oluşturduğunuzu varsayalım. Bu tür bir uygulamanın API uç noktalarını bildirmesine gerek yoktur; yalnızca bir API uç noktasına erişebilmesi gerekir.

İyon

Bu, bu tür bir erişim için harika bir kütüphanedir.

Lütfen msysmilu'nun harika cevabını okuyun ( https://stackoverflow.com/a/28559884/1024412 )

HTTP üzerinden resim yükleme

Volley

Volley, ReST API'leri için de kullanılabilir, ancak daha karmaşık kurulum nedeniyle, Retrofit'i yukarıdaki gibi kullanmayı tercih ederim ( http://square.github.io/retrofit/ )

Bir sosyal ağ uygulaması oluşturduğunuzu ve arkadaşlarınızın profil resimlerini yüklemek istediğinizi varsayalım.

build.gradle

Bu satırı Modül düzeyinize ekleyin buid.gradle:

implementation 'com.android.volley:volley:1.0.0'

ImageFetch.java

Volley, Retrofit'ten daha fazla kurulum gerektirir. Bir RequestQueue, bir ImageLoader ve bir ImageCache kurmak için böyle bir sınıf oluşturmanız gerekir, ancak bu çok kötü değil:

public class ImageFetch {
    private static ImageLoader imageLoader = null;
    private static RequestQueue imageQueue = null;

    public static ImageLoader getImageLoader(Context ctx){
        if(imageLoader == null){
            if(imageQueue == null){
                imageQueue = Volley.newRequestQueue(ctx.getApplicationContext());
            }
            imageLoader = new ImageLoader(imageQueue, new ImageLoader.ImageCache() {
                Map<String, Bitmap> cache = new HashMap<String, Bitmap>();
                @Override
                public Bitmap getBitmap(String url) {
                    return cache.get(url);
                }
                @Override
                public void putBitmap(String url, Bitmap bitmap) {
                    cache.put(url, bitmap);
                }
            });
        }
        return imageLoader;
    }
}

user_view_dialog.xml

Resim eklemek için düzen xml dosyanıza aşağıdakileri ekleyin:

<com.android.volley.toolbox.NetworkImageView
    android:id="@+id/profile_picture"
    android:layout_width="32dp"
    android:layout_height="32dp"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    app:srcCompat="@android:drawable/spinner_background"/>

UserViewDialog.java

OnCreate yöntemine (Fragment, Activity) veya yapıcıya (Dialog) aşağıdaki kodu ekleyin:

NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());

Picasso

Square'den bir başka mükemmel kütüphane. Bazı harika örnekler için lütfen siteye bakın: http://square.github.io/picasso/


16

Basit bir deyişle,

UI İPLİKTE AĞ ÇALIŞMAYIN

Örneğin, bir HTTP isteği yaparsanız, bu bir ağ eylemidir.

Çözüm:

  1. Yeni bir Konu oluşturmanız gerekiyor
  2. Veya AsyncTask sınıfını kullanın

Yolu:

Tüm çalışmalarınızı içeri koyun

  1. run() yeni iplik yöntemi
  2. Veya doInBackground() AsyncTask sınıfının yöntemi.

Fakat:

Ağ yanıtından bir şey aldığınızda ve bunu görünümünüzde göstermek istediğinizde (TextView'da yanıt mesajını görüntüleme gibi), kullanıcı arayüzü iş parçacığına geri dönmeniz gerekir .

Eğer yapmazsan, alacaksın ViewRootImpl$CalledFromWrongThreadException.

Nasıl?

  1. AsyncTask kullanırken, onPostExecute()yöntemi yöntemden güncelleyin
  2. VeyarunOnUiThread() yöntemi arayın ve yöntemin içindeki görünümü güncelleyin run().

12

ANR , NetworkOnMainThreadException , IllegalStateException'ı boşaltmak main threadve almaktan kaçınmak için kodunuzun bir bölümünü başka bir iş parçacığına taşıyabilirsiniz (örn., Ana iş parçasındaki veritabanına erişilemiyor çünkü UI'yi uzun süre kilitleyebilir).

Duruma bağlı olarak seçmeniz gereken bazı yaklaşımlar var

Java İş Parçacığı veya Android İşleyicisi

Java iş parçacıkları tek kullanımlıktır ve çalıştırma yöntemini uyguladıktan sonra ölür.

HandlerThread bir lüper olan yeni bir iş parçacığı başlatmak için kullanışlı bir sınıftır.

AsyncTask

AsyncTask , Thread ve Handler etrafında yardımcı bir sınıf olarak tasarlanmıştır ve genel bir iş parçacığı çerçevesi oluşturmaz. AsyncTasks ideal olarak kısa işlemler için kullanılmalıdır (en fazla birkaç saniye). İş parçacıklarını uzun süre çalışmaya devam etmeniz gerekiyorsa, java.util.concurrent paketi tarafından sağlanan çeşitli API'ları kullanmanız önemle tavsiye edilir. Yürütücü , ThreadPoolExecutor ve FutureTask .

İş parçacığı havuzu uygulaması ThreadPoolExecutor , ScheduledThreadPoolExecutor ...

İş parçacığı havuzu üzerinde ince kontrol sağlayan ExecutorService uygulayan ThreadPoolExecutor sınıfı (Örneğin, çekirdek havuz boyutu, maksimum havuz boyutu, canlı kalma süresi, vb.)

ScheduledThreadPoolExecutor - ThreadPoolExecutor öğesini genişleten bir sınıf. Belirli bir gecikmeden sonra veya periyodik olarak görevleri zamanlayabilir.

FutureTask

FutureTask eşzamansız işleme gerçekleştirir, ancak sonuç henüz hazır değilse veya işleme tamamlanmadıysa, get () öğesini çağırmak iş parçacığını engeller

AsyncTaskLoaders

AsyncTaskLoaders, AsyncTask'ın doğasında olan birçok sorunu çözdüğü için

IntentService

Bu, Android'de uzun süre çalışan işleme için defacto seçimdir, iyi bir örnek büyük dosyaları yüklemek veya indirmek olabilir. Kullanıcı uygulamadan çıksa ve bu görevler devam ederken kullanıcının uygulamayı kullanmasını kesinlikle engellemek istemeseniz de yükleme ve indirme işlemi devam edebilir.

JobScheduler

Etkili bir şekilde, hizmetin ne zaman çalıştırılacağına ilişkin ölçütlerinizi belirten JobInfo.Builder kullanarak bir Hizmet oluşturmanız ve bir iş oluşturmanız gerekir.

RxJava

Gözlenebilir diziler kullanarak eşzamansız ve olay tabanlı programlar oluşturmak için kütüphane.

Coroutines (Kotlin)

Ana özü, asenkron kodun senkron gibi görünmesini sağlar

Burada , burada , burada , burada daha fazlasını okuyun


Benim için çalıştı ... AsyncTask'ı yoğun bir şekilde kullandım, ancak bir görev çalışırken başka bir görev bekler. Bunu çözmek istiyorum. Şimdi executeonexecutor ile çalışıyor. Düşük bellek cihazlarında nasıl davranacağına bakalım.
Shingade Suresi

Lütfen yönteme bir göz atın: asyncTask.executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR, params); görevinizi eşzamanlı olarak çalıştırmak için
yoAlex5

10

Yukarıda büyük bir çözüm havuzu olmasına rağmen, hiç kimse belirtilmedi com.koushikdutta.ion: https://github.com/koush/ion

Ayrıca eşzamansız ve kullanımı çok basit :

Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
   @Override
    public void onCompleted(Exception e, JsonObject result) {
        // do stuff with the result or error
    }
});

10

Yeni Threadve AsyncTask çözümleri zaten açıklanmıştır.

AsyncTaskideal olarak kısa operasyonlar için kullanılmalıdır. ThreadAndroid için normal tercih edilmez.

HandlerThread ve Handler kullanarak alternatif çözümlere göz atın

HandlerThread

Bir lüper olan yeni bir iplik başlatmak için kullanışlı sınıf. İlmek yapıcı daha sonra işleyici sınıfları oluşturmak için kullanılabilir. start()Yine de çağrılması gerektiğini unutmayın .

işleyici:

Bir işleyici, bir iş parçacığının MessageQueue ile ilişkili Message ve Runnable nesneleri göndermenizi ve işlemenizi sağlar. Her Handler örneği tek bir iş parçacığı ve o iş parçacığının ileti kuyruğu ile ilişkilendirilir. Yeni bir İşleyici oluşturduğunuzda, onu oluşturan iş parçacığının iş parçacığı / ileti kuyruğuna bağlanır - bu noktadan sonra, bu ileti kuyruğuna ileti ve runnable iletir ve iletiden çıktıkça bunları yürütür Sıra.

Çözüm:

  1. Oluşturmak HandlerThread

  2. Çağrı start()üzerineHandlerThread

  3. HandlerKaynağını Looperkullanarak oluşturunHanlerThread

  4. Ağ işlemiyle ilgili kodunuzu Runnablenesneye gömün

  5. Gönder RunnableGöreviHandler

Örnek kod snippet'i, hangi adres NetworkOnMainThreadException

HandlerThread handlerThread = new HandlerThread("URLConnection");
handlerThread.start();
handler mainHandler = new Handler(handlerThread.getLooper());

Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        try {
            Log.d("Ravi", "Before IO call");
            URL page = new URL("http://www.google.com");
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ( (line =  buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Ravi", "After IO call");
            Log.d("Ravi",text.toString());

        }catch( Exception err){
            err.printStackTrace();
        }
    }
};
mainHandler.post(myRunnable);

Bu yaklaşımı kullanmanın artıları:

  1. Thread/AsyncTaskHer ağ işlemi için yeni oluşturmak pahalıdır. Bu Thread/AsyncTaskyok edilecek ve bir sonraki Ağ işlemleri için yeniden oluşturulacaktır. Ama birlikte Handlerve HandlerThreadyaklaşım, sen tek için (Runnable görevler gibi) birçok ağ işlemlerini gönderebilirsiniz HandlerThreadkullanarak Handler.

8

RxAndroidbu soruna başka bir daha iyi bir alternatiftir ve bizi Android oluşturma ve ardından sonuçları Android UI iş parçacığına gönderme sorunlarından kurtarır. Sadece görevlerin yürütülmesi gereken iş parçacıklarını belirtmemiz ve her şeyin dahili olarak ele alınması gerekir.

Observable<List<String>> musicShowsObservable = Observable.fromCallable(new Callable<List<String>>() { 

  @Override 
  public List<String> call() { 
    return mRestClient.getFavoriteMusicShows(); 
  }
});

mMusicShowSubscription = musicShowsObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<String>>() {

    @Override 
    public void onCompleted() { }

    @Override 
    public void onError(Throwable e) { }

    @Override 
    public void onNext(List<String> musicShows){
        listMusicShows(musicShows);
    }
});
  1. Specifiying göre (Schedulers.io()), RxAndroid çalışacak getFavoriteMusicShows() farklı bir iş parçacığı üzerinde.

  2. Kullanarak AndroidSchedulers.mainThread()UI iş parçacığında bu Gözlemlenebilir gözlemlemek istiyoruz, yani onNext()geri aramamızın UI iş parçacığında çağrılmasını istiyoruz


8

Ana iş parçacığı UI iş parçacığıdır ve ana iş parçacığında kullanıcı etkileşimini engelleyebilecek bir işlem yapamazsınız. Bunu iki şekilde çözebilirsiniz:

Ana iş parçacığında görevi böyle yapmaya zorlayın

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

Veya basit bir işleyici oluşturun ve isterseniz ana iş parçacığını güncelleyin.

Runnable runnable;
Handler newHandler;

newHandler = new Handler();
runnable = new Runnable() {
    @Override
    public void run() {
         try {
            //update UI
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
};
newHandler.post(runnable);

Ve iplik kullanımını durdurmak için:

newHandler.removeCallbacks(runnable);

Daha fazla bilgi için şu konulara bakın : Ağrısız diş çekme


Teşekkür. Sürüm 1, onCreate'a ilk Eylem olarak eklerken yardımcı olur.
Ingo

7

Bu çalışıyor. Dr.Luiji'nin cevabını biraz daha basitleştirdim.

new Thread() {
    @Override
    public void run() {
        try {
            //Your code goes here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}.start();

7

Android'de ağ işlemleri ana iş parçacığında çalıştırılamaz. Ağ işlemleri yapmak için İş parçacığı, AsyncTask (kısa çalışan görevler), Hizmet (uzun çalışan görevler) kullanabilirsiniz.


7

Ağ kaynaklarına ana (UI) iş parçacığından erişmek bu özel duruma neden olur. Bu sorunu önlemek için bir ağ kaynağına erişmek için ayrı bir iş parçacığı veya AsyncTask kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.