53 Soru: Android.os.NetworkOnMainThreadException yazılımını nasıl düzeltirim?

tarafından oluşturulan soru Sat, Feb 3, 2018 12:00 AM

Android projemi RssReader için çalıştırırken bir hata oluştu.

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?

    
2231
  1. Bu blog gönderisini okuyun . Bunun neden Android 3.0 ve üstünde gerçekleştiğini açıklıyor.
    2012-08-07 12: 38: 46Z
  2. Rite izinde olmak, önce androiddeki Ağ İstekleri hakkında daha sonra okumak ve ardından "Voleybolu" çalışmayı tavsiye ederim.
    2014-01-23 06: 39: 11Z
  3. Bu sorunu çözen birçok alternatif kitaplık var. Pek çok kişi bu sayfanın altında listelenmiştir. . Daha fazlasına sahipseniz, onları alırız :)
    2014-02-11 22: 55: 24Z
  4. İnternet faaliyetlerini ana (UI) dizisinden ayrı bir dizide çalıştırmanız gerekiyor
    2014-10-30 20: 44: 18Z
  5. stackoverflow.com/questions/16439587/… yukarıdaki bağlantı iyidir
    2015-01-01 05: 12: 18Z
30 Yanıtlar                              30                         

Bu istisna, bir uygulama ana iş parçacığında bir ağ oluşturma işlemi gerçekleştirmeye çalıştığında ortaya çıkar. Kodunuzu AsyncTask adresinde çalıştırın:

 
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 yapılır:

MainActivity.java dosyasında bu satırı oncreate() yönteminize ekleyebilirsiniz

 
new RetrieveFeedTask().execute(urlToRssFeed);

Bunu AndroidManifest.xml dosyaya eklemeyi unutmayın:

 
<uses-permission android:name="android.permission.INTERNET"/>
    
2438
2017-11-28 11: 57: 55Z
  1. Burada, yukarıdaki kod parçacığının bir alt sınıf (iç sınıf), tercihen özel olduğu varsayılmasının kayda değer olduğunu düşünüyorum. Bu şekilde AsyncTask tamamlandığında, sınıfınızın iç taraflarını hala değiştirebilirsiniz.
    2012-07-22 05: 57: 08Z
  2. Aslında yukarıda belirtilenle aynı şeyi yaptım, ancak bu hatayla karşılaştığımda m yaptım java.lang.RuntimeException: İşlenmemiş iş parçacığı içinde işleyici oluşturulamıyor Looper.prepare ()
    2016-08-30 11: 08: 21Z
  3. Bu tam olarak yanlış bir cevap. Bunu her zaman halklar kodunda karşıladım ve her şeyi düzeltmek için can sıkıcı durumdayım. saati. AsyncTask ağ aktivitesi için kullanılmamalıdır, çünkü aktiviteye bağlıdır, fakat aktivite yaşam döngüsüne bağlı değildir. Cihazın bu görevle çalıştırılması bir istisnaya neden olacak ve uygulamanızın çökmesine neden olacaktır. Verileri sqlite veritabanına bırakan bir IntentService kullanın.
    2016-09-09 19: 08: 12Z
  4. Dikkat, AsyncTask, olmamalıdır olması durumunda genellikle etkinlik başına ağ işlemleri için kullanılır. yaşam döngüsü, etkinlikle senkronize değil. Veri almak için bir IntentService ve görünümün arkasındaki veritabanını kullanmanız gerekir.
    2016-10-05 21: 24: 09Z
  5. @ BrillPappin, FWIW, bu Android Geliştirici Kılavuzu AsyncTask kullanıyor ve bir yapılandırma değişikliğine bakıyor.
    2019-04-11 22: 23: 18Z

Ağ işlemlerini neredeyse her zaman bir iş parçacığında veya zaman uyumsuz bir görev olarak gerçekleştirmelisiniz.

Ancak bu kısıtlamayı kaldırmak mümkündür ve sonuçları kabul etmek istiyorsanız, varsayılan davranışı geçersiz kılarsınız.

Add:

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

StrictMode.setThreadPolicy(policy); 

Sınıfınızda,

ve

Bu izni android manifest.xml dosyasına ekleyin:

 
<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şlama algılayacak ve bir zorla öldürme yapmak zorunda kalacak ve etkinlik yöneticisinin uygulamanızı öldürmesi ve kullanıcıya uygulamanın durduğunu söylemesi riskiyle karşı karşıya kalacaksınız .

Android, duyarlılık için tasarım yapmak için iyi programlama uygulamaları hakkında iyi ipuçlarına sahiptir: http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

    
627
2018-02-11 14: 18: 49Z
  1. Bu çok kötü bir fikir. Çözüm, ana konudaki ağ IO'sundan kaçınmaktır (kabul edilen cevabın gösterdiği gibi).
    2012-05-14 14: 10: 56Z
  2. Bununla sadece asıl sorununuzu gizlersiniz.
    2012-06-18 06: 44: 01Z
  3. @ TwistedUmbrella AsyncTask bir kod sayfası eklemez, 6 satır ekler (sınıf bildirimi, geçersiz kılma notunu, doInBackground bildirimi, 2 kapanış ayracı ve execute()'a yapılan çağrı) . Öte yandan, bahsettiğiniz bir siteden tek bir alım bile UI'nin yanıt vermesinde önemli bir gecikme getiriyor. Tembel olmayın.
    2012-09-04 09: 39: 36Z
  4. Uygun AsyncTask'ı uygulamadan önce bir şeyin işe yarayıp yaramadığını görmek için sadece bir kod parçası çalıştırmayı düşünüyorsanız, bunun mükemmel bir çözüm olduğunu düşünüyorum. Bu nedenle, bu cevabı geri aldım, diğerlerinin de söylediği gibi, bu bir üretim uygulamasında yapılmamalı, ancak dev test için hızlı bir çözüm olarak yapılmalı.
    2013-02-09 06: 49: 20Z
  5. Olumsuz. Bu cevap doğrudur ve ne saf ne de aptal olmayan, ancak basitçe SYNCHRONOUS (yani: bu uygulamayı engellemeli ) çağrısını gerektiren birçok programcı için bu tam olarak ihtiyaç duyulan şeydir. Android'in varsayılan olarak istisnayı attığı için çok mutluyum (IMHO, yapmak için çok "yararlı" bir şey!) - ama aynı şekilde "teşekkür ederim, ama - bu aslında benim istediğim şey" derken ve geçersiz kıldığım için eşit derecede mutluyum. o.
    2013-05-01 06: 48: 01Z

Bu sorunu yeni bir Thread kullanarak çözdüm.

 
Thread thread = new Thread(new Runnable() {

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

thread.start(); 
    
396
2016-10-05 09: 42: 24Z
  1. Her ağ işlemi gerçekleştirmek istediğinizde yeni bir iş parçacığı oluşturmak yerine, tek bir iş parçacığı yürütücü hizmeti de kullanabilirsiniz.
    2013-01-27 18: 06: 36Z
  2. Basit ama tehlikeli. Anonim Runnable, çevreleyen sınıfa (ör. Faaliyetiniz veya Parçanız) çöp atılmasını önleyen örtük bir referansa sahiptir.iplik tamamlanana kadar toplanır. En azından önceliği Process.BACKGROUND olarak ayarlamalısınız, aksi takdirde bu iş parçacığı ana /kullanıcı iş parçacığıyla aynı öncelikte çalışacaktır, yaşam döngüsü yöntemleri ve kullanıcı arabirimi kare hızları (koreografın günlüğündeki uyarılara dikkat edin). div>
    2014-06-19 12: 39: 39Z
  3. @ Stevie önceliği nasıl ayarlamalı? ne runnble ne de executorService böyle bir belirleyici yönteme sahip değil
    2015-05-31 13: 26: 02Z
  4. @ J.K. ExecutorService'ınıza özel bir ThreadFactory sağlayın ve iade etmeden önce thread'da Thread.setPriority'yi arayın.
    2015-06-01 19: 14: 03Z
  5. Şebeke çağrısı yapması amaçlanan bir şey için öncelik belirleme (engellenecek) fazlaca görünüyor.
    2016-01-27 13: 09: 20Z

Kabul edilen cevabın bazı önemli yönleri vardır. Ne yaptığınızı bilmiyorsanız gerçekten sürece ağ iletişimi için AsyncTask kullanmanız önerilmez. Aşağı taraflardan bazıları şunlardır:

  • Statik olmayan iç sınıflar olarak oluşturulan AsyncTask, çevreleyen Faaliyet nesnesine, içeriğine ve bu etkinlik tarafından oluşturulan tüm Görünüm hiyerarşisine açık bir referansa sahiptir. Bu başvuru AsyncTask'ın arka plan çalışması tamamlanana kadar Faaliyetin toplanmasını önler. Kullanıcının bağlantısı yavaşsa ve /veya indirme işlemi büyükse, bu kısa süreli bellek sızıntıları bir sorun olabilir - örneğin, yönlendirme birkaç kez değişirse (ve yürütme görevlerini iptal etmiyorsanız) veya kullanıcı Faaliyetten uzakta.
  • AsyncTask, üzerinde çalıştığı platforma bağlı olarak farklı yürütme özelliklerine sahiptir: API düzey 4'ten önce AsyncTasks, tek bir arka plan iş parçacığında seri olarak yürütülür; API seviyesi 4'ten API seviyesi 10'a kadar AsyncTasks, 128 konuya kadar olan bir havuzda çalıştırılır; API seviye 11'den itibaren AsyncTask, tek bir arka plan iş parçacığında seri olarak çalıştırılır (aşırı yüklenmiş executeOnExecutor yöntemini kullanmazsanız ve alternatif bir yürütücü tedarik etmezseniz). Seri olarak ICS'de çalıştırıldığında düzgün çalışan kod, Gingerbread'te eşzamanlı olarak yürütüldüğünde kırılabilir, örneğin, yanlışlıkla yürütme sırası bağımlılıklarınız varsa.

Kısa süreli hafıza sızıntılarından kaçınmak, tüm platformlarda iyi tanımlanmış yürütme özelliklerine sahip olmak ve gerçekten güçlü ağ kullanımı sağlamak için bir temele sahip olmak istiyorsanız, şunu göz önünde bulundurmak isteyebilirsiniz:

  1. Sizin için iyi iş çıkaran bir kütüphane kullanmak - bu soru ya da
  2. Sonucu, Service veya IntentService kullanarak, belki de PendingIntent ile, Faaliyet'in onActivityResult yöntemi ile döndürmek için.

IntentService yaklaşımı

Aşağı tarafta:

  • Düşündüğünüz kadar olmasa da, AsyncTask'dan daha fazla kod ve karmaşıklık
  • İstekleri sıraya koyacak ve bunları tek bir arka plan iş parçacığında çalıştıracak. Bunu, IntentService'u, örneğin bunu .
  • Um, şu anda başkalarını düşünemiyorum aslında

Yukarı tarafta:

  • Kısa süreli hafıza sızıntısı sorununu önler
  • Ağ işlemleriniz devam ederken etkinliğiniz yeniden başlarsa, Service yöntemiyle indirme işleminin sonucunu yine de alabilirsiniz
  • Sağlam ağ kodu oluşturmak ve yeniden kullanmak için AsyncTask'tan daha iyi bir platform. Örnek: önemli bir yükleme yapmanız gerekiyorsa, onActivityResult’da AsyncTask’dan bunu yapabilirsiniz, ancak kullanıcı bir telefon görüşmesi yapmak için uygulama kapsamı dışına çıkarsa, sistem olabilir yükleme tamamlanmadan önce uygulama. Etkin bir Activity ile bir uygulamayı öldürmek daha az olasıdır .
  • Eşzamanlı Service sürümünü kullanıyorsanız (yukarıda bağladığım sürüm gibi) eşzamanlılık seviyesini IntentService üzerinden kontrol edebilirsiniz.

Uygulama özeti

Tek bir arka plan iş parçacığından çıkmak için indirme yapmak için Executor uygulayabilirsiniz.e kolayca.

1. Adım: İndirme işlemini gerçekleştirmek için bir IntentService oluşturun. IntentService ekstralar aracılığıyla ne indireceğini söyleyebilir ve sonucu Intent'a döndürmek için bir PendingIntent iletebilirsiniz:

 Activity

2. Adım: Hizmeti bu bildirime kaydedin:

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

3. Adım: Hizmeti, sonucu döndürmek için kullanacağı bir PendingResult nesnesini ileterek Aktiviteden çağırın:

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

4. Adım: Sonucu onActivityResult ile işleyin:

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

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

    
148
2017-05-23 12: 34: 44Z
  1. IntentService, AsyncTask tam olarak yapmamanın yolu olduğu için, kaldırılmamak için doğru yoldur.
    2016-09-10 14: 59: 39Z
  2. @ BrillPappin AsyncTask'in sakıncalarını vurgulamak için neredeyse tamamen aynı fikirdeyim ve yeniden ifade ettim. (Hala ne yaptığınızı biliyorsanız - çok az sayıda vaka olduğunu düşünüyorum - AsicTask'ı kullanmanın olabileceği olabilir, ancak kabul edilen cevap sakıncaları işaret etmeyin ve Android'in yararı için çok popülerdir).
    2017-03-13 12: 56: 14Z
  3. Gerçekten
    @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);
    }
    
    'a ihtiyacınız var mı? RSS şeyleriyle çalışmıyorsanız ne olacak?
    2018-04-14 19: 13: 12Z
  4. Bunun en iyi cevap olduğunu düşünüyorum, yalnızca istisnadan kurtulmaya odaklanmıyor, aslında en uygun koşulları da göz önüne alıyor.
    2019-02-01 16: 00: 43Z
  5. Bence Google, berdonu programcılar tarafına koymak yerine, kötü atık toplama uygulamalarını değiştirmeli. Bu işletim sisteminin sorumluluğundadır. Bir programcı Android uygulamasındaki temel sorun nedeniyle işi yapmak için IntentService veya Hizmet 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 Android kötü bellek yönetimini programcılar değil çözmelidir.
    2019-06-04 10: 31: 12Z

UI iş parçacığı üzerindeki Bal peteği . Teknik olarak, Android'in önceki sürümlerinde mümkündür, ancak uygulamanızın yanıt vermemesine neden olacağı ve işletim sisteminin kötü davrandığı için öldürülmesiyle sonuçlanabileceği için gerçekten kötü bir fikirdir. Bir arkaplan işlemi çalıştırmanız veya ağ işleminizi arkaplan iş parçacığında gerçekleştirmek için AsyncTask kullanmanız gerekir.

Android'de Ağrısız Diş Açma hakkında bir makale var. Bunun için iyi bir giriş olan geliştirici sitesi ve size burada gerçekçi olarak verilebilecek olandan çok daha iyi bir cevap derinliği sağlayacaktır.

    
139
2014-02-09 16: 25: 22Z
  1. strictMode kullanmayın (yalnızca hata ayıklama modunda)
  2. SDK sürümünü değiştirmeyin
  3. Ayrı bir iş parçacığı kullanmayın

Hizmet veya AsyncTask Kullan

Ayrıca Yığın Taşması sorusuna da bakın:

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

    
71
2017-05-23 12: 26: 38Z
  1. Belki de bir Servis kullanıyorsanız, ayrı bir iş parçacığı oluşturmanız gerekebileceğini vurgulamaya değer - ana iş parçacığında çalışan Servis geri aramaları. Diğer yandan, bir IntentService onHandleIntent yöntemini bir arka plan iş parçacığında çalıştırır.
    2014-01-22 08: 33: 50Z
  2. uzun süren işlemler için bir AsyncTask kullanmamalısınız! Yönergeler en fazla 2 ila 3 saniye belirtir.
    2014-02-04 10: 41: 15Z

Ağ başka bir iş parçacığında hareket ediyor mu

  

Örnek İçin:

 IllustrativeRSS

Ve bunu AndroidManifest.xml dosyasına ekleyin

 
new Thread(new Runnable(){
    @Override
    public void run() {
        // Do network action in this function
    }
}).start();
    
66
2016-09-13 19: 49: 55Z
  1. Ancak, UI iş parçacığında bir sonraki görev takımını yürütebilmemiz için iş parçacığının bu işlemi ne zaman bitirdiğini nasıl öğrenebiliriz? AsyncTask bunu yapabilme imkanı sağlıyor. Runnable thread kullanarak aynı şeyi yapmanın bir yolu var mı?
    2014-01-04 23: 30: 41Z
  2. Kodunuzu adım adım işleyecektir, bu nedenle kodun sonunda işlem tamamlandığında, işleyiciyi UI thread'a geri döndürmeniz gerekir
    2014-01-05 02: 18: 05Z
  3. 2014-01-06 00: 50: 28Z
  4. Çalışan iş parçacığı üzerinde yürütüldüğü için eşzamansız görev veya niyet hizmeti kullanabilirsiniz.
    2017-04-19 20: 05: 38Z

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

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

Bu önerilmez :

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

Her iki yöntem için de tam kod

    
56
2015-08-20 09: 04: 29Z
  1. Evet ANR hatası gelirdi. Uygulama 5 saniye içinde yanıt vermiyor demektir.
    2013-05-06 11: 23: 50Z
  2. Bu gerçekten kötü bir cevap. İş parçacığının politikasını değiştirmemelisiniz ancak daha iyi kod yazmalısınız: ana iş parçasında ağ işlemleri yapmayın!
    2013-08-29 15: 01: 25Z
  3. @ Sandeep Siz ve diğer izleyiciler bunu da okumalısınız. stackoverflow.com/a/18335031/3470479
    2016-09-15 14: 06: 01Z

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

Bu, bir alt iş parçacığında bir görevi nasıl çalıştırdığınızdır:

 AsyncTask     
49
2016-06-22 21: 08: 38Z
  1. Anonim Çalıştırılabilir en iyi yol DEĞİLDİR, çünkü etrafını saran sınıfa açık bir referansı vardır ve iş parçacığı tamamlanıncaya kadar GC'nin girmesini önler! Ayrıca, bu iş parçacığı ana /ABD iş parçacığı ile aynı öncelikte çalışacaktır. yaşam döngüsü yöntemleri ve UI kare oranları ile!
    2016-03-12 13: 18: 24Z

Kodunuzu içeri koyun:

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

Veya:

 
new Thread(new Runnable(){
    @Override
    public void run() {
        try {
            // Your implementation
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}).start();
    
46
2016-06-22 21: 13: 15Z
  1. İkincisi, 11 yaşın üzerindeki api için ilk önce en iyisi olacak
    2014-07-28 10: 52: 31Z
  2. , aşağıdaki yorumu okuyun: stackoverflow.com/a/21107128/1429432
    2016-03-12 13: 19: 43Z

Android Ek Açıklamaları kullanmak bir seçenektir. Herhangi bir yöntemi bir arka plan dizisinde çalıştırmanıza izin verecektir:

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

Dikkat, basitlik ve okunabilirlik avantajları sağlamasına rağmen, dezavantajları vardır.

    
43
2015-04-30 16: 46: 11Z
  1. @ Gavriel, not aldığınız her şeyin kopyasını oluşturur, ister yöntem, etkinlik, fragman, singleton, isterse kodun iki katı olması ve derlenmesi daha uzun sürüyor o. Ayrıca kütüphanedeki hatalardan dolayı bazı sorunları olabilir. Hata ayıklamak ve hata bulmak daha zor olacaktı.
    2015-08-19 01: 30: 33Z

Bu Android 3.0 ve üzeri sürümlerde olur. Android 3.0 ve üzeri sürümlerde, ağ işlemlerini (İnternete erişen işlevler) ana iş parçacığı /UI iş parçacığında çalıştırmayı (sizin oluşturduğunuzda oluşturduğunuzdan ve etkinlikteki özgeçmiş yöntemlerinden kaynaklanan) kısıtladılar.

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

    
42
2014-02-09 16: 27: 30Z

Hata, ana iş parçacığında uzun süren işlemleri gerçekleştirmekten kaynaklanıyor, AsynTask veya Konu . Daha iyi kullanım için bu kütüphaneyi AsyncHTTPClient üzerinden kontrol edebilirsiniz.

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

@Background
protected void doSomething() 
    // run your networking code here
}
    
39
2017-09-07 04: 53: 07Z

Ana iş parçacığında (UI iş parçacığı) herhangi bir ağ işlemi, dosya G /Ç veya SQLite veritabanı işlemleri gibi zaman alan bir işlem yapmamalısınız. Bu tür bir işlem için bir çalışan iş parçacığı oluşturmalısınız, ancak sorun şu ki, çalışan iş parçacığınızdan UI ile ilgili herhangi bir işlemi doğrudan gerçekleştiremezsiniz. Bunun için

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
    }
});
'u kullanmanız ve Handler'u geçmeniz gerekir.

Tüm bunları basitleştirmek için Android, Message, AsyncTask, AsyncTaskLoader gibi çeşitli yollar sunarveya CursorLoader. Böylece bunlardan herhangi birini gereksinimlerinize göre kullanabilirsiniz.

    
38
2014-02-09 16: 29: 41Z

Üst spektom yanıtı mükemmel çalışıyor.

/p>

IntentService satır içi yazı yazıyorsanız ve bir sınıf olarak genişlemiyorsanız ve bunun üzerine, AsyncTask’dan yanıt almanız gerekiyorsa, AsyncTask yöntemini aşağıdaki gibi kullanabilirsiniz.

 get()

(Onun örneğinden.)

    
37
2017-05-23 11: 47: 29Z
  1. RSSFeed feed = new RetreiveFeedTask().execute(urlToRssFeed).get();
    
    kullanmak kötü bir fikir ... AsyncTask'ı tekrar "senkronize et" yapıyor
    2013-09-17 15: 29: 51Z
  2. Bundan daha iyi bir yolu var mı? @Selvin
    2013-09-20 20: 50: 25Z
  3. Sonuç hakkında ana konuyu bilgi edinebileceğinizi düşünüyorum. Örneğin, sonuç dahil ana dizine bir yayın gönderin.
    2015-02-10 02: 35: 41Z

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

Hata SDK uyarısıdır!

    
31
2016-06-22 21: 09: 34Z

Benim için bu şuydu:

 get()

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

Hedef sürümün Android Hedef Kütüphanenizle aynı olduğundan emin olun. Hedef kütüphanenizin ne olduğundan emin değilseniz, Projenize sağ tıklayın - > Yol Oluştur - > Android ve işaretli olan olmalı.

Ayrıca, başkalarının da belirttiği gibi, İnternet’e erişim için doğru izinleri ekleyin:

 
<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="10" />
    
26
2016-06-22 21: 07: 28Z
  1. Burada ne yaptığınızı size açıklamama izin verin:
    <uses-permission android:name="android.permission.INTERNET"/>
    
    , size söyleyen Guardian'dır: kendi ayağınıza ateş etme ... çözümünüz: hadi gidelim Eskiden Guardian olmadığında geçmişe döndüm - şimdi serbestçe ayağımı vurabilirim
    2013-09-17 15: 36: 09Z
  2. Bu yaklaşımı ben de kullandım ve hiçbir sorun yaşamadım. Guardian bazen çok telaşlı.
    2013-10-25 19: 36: 09Z

Sadece bir şeyi açıkça hecelemek için:

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

Dolayısıyla, ana iş parçacığında ağ oluşturma işlemlerini yapamayacağınızı söylemek, UI iş parçacığında ağ oluşturma işlemlerini yapamayacağınız anlamına gelir; bu, başka bir iş parçacığının içinde NetworkOnMainThreadException bloğunda ağ işlemlerini yapamayacağınız anlamına gelir .

(Neden ana hatayımdan başka bir yere bu hatayı aldığımı anlamaya çalışırken uzun bir kafa kaşıma anı yaşadım. Bu yüzden; bu konu yardım etti; umarım bu yorum birine yardımcı olur.Başka.)

    
23
2014-06-24 21: 32: 53Z

Bu istisna, ana iş parçasında gerçekleştirilen ve ağır iş nedeniyle çok fazla zaman alıyorsa .

gerçekleşir.

Bundan kaçınmak için, iş parçacıkları veya işveren

kullanarak başa çıkabiliriz.  *runOnUiThread(new Runnable() { ... }*     
21
2016-06-22 21: 12: 36Z

Bunu Faaliyetinizde Kullanın

 
Executors.newSingleThreadExecutor().submit(new Runnable() {
    @Override
    public void run() {
        // You can perform your task here.
    }
});
    
20
2018-12-03 12: 07: 24Z

Bu soruda zaten çok sayıda harika cevap var, ancak bu cevapların yayınlanmasından bu yana birçok büyük kitaplık çıktı. Bu bir tür acemi rehber olarak tasarlanmıştır.

Ağ işlemlerini gerçekleştirmek için çeşitli kullanım durumlarını ve her biri için a 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 döviz kurlarını takip etmelerini sağlayan bir uygulama yazdığınızı varsayalım. Şuna benzeyen bir Json API'sı bulursunuz:

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

Meydandan Güçlendirme

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

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

build.gradle

Bu satırları Modül seviyenize ekleyin buid.gradle:

 
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)

FinancesApi.java

 
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

FinancesApiBuilder

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

FinancesFragment snippet'i

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

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

Bir kerede ReST API erişimi

Kullanıcıların GPS konumunu arayan ve o bölgedeki mevcut sıcaklığı kontrol eden ve onlara ruh halini söyleyen bir "hava durumu havası" uygulaması oluşturduğunuzu varsayalım. Bu tür bir uygulamanın, API bitiş noktaları bildirmesi gerekmez; sadece bir API uç noktasına erişebilmesi gerekiyor.

İyon

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

Lütfen msysmilu'in en iyi yanıtını okuyun ( https://stackoverflow.com/a/28559884/1024412 ) >

Görüntüleri HTTP üzerinden yükleme

Volley

Voleybolik ReST API'leri için de kullanılabilir, ancak daha karmaşık kurulum nedeniyle, Retrofit'i yukarıdaki gibi Kare'den 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 seviyenize ekleyin buid.gradle:

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

ImageFetch.java

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

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

user_view_dialog.xml

Resim eklemek için mizanpaj xml dosyanıza aşağıdakileri ekleyin:

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

UserViewDialog.java

Aşağıdaki kodu onCreate yöntemine (Fragment, Activity) veya yapıcıya (Dialog) 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"/>

Picasso

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

16
2018-03-17 08: 26: 37Z
  1. bu, mevcut dünyada 2017'de android ağının uygulanmasını basitleştirdiği için orijinal cevaptan daha iyi bir cevap olmalıdır ve gerçek dünyadaki uygulamaların çoğu, bunun gibi çok iyi kütüphaneler kullanmaktadır. div>
    2017-11-28 11: 46: 46Z

    Basit bir deyişle,

    UI İPLİĞİNDE AĞ ÇALIŞMAYIN

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

    Çözüm:

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

    Yolu:

    Tüm çalışmalarını içine koy

    1.  
      NetworkImageView profilePicture = view.findViewById(R.id.profile_picture);
      profilePicture.setImageUrl("http://example.com/users/images/profile.jpg", ImageFetch.getImageLoader(getContext());
      
      yeni iş parçacığı yöntemi
    2. Veya run() AsyncTask sınıfının yöntemi.

    Ama:

    Ağ yanıtından bir şey aldığınızda ve bunu görünümünüzde göstermek istediğinizde (TextView'deki ekran yanıtı mesajı gibi), kullanıcı arayüzüne geri dönme dizisine gitmeniz gerekir.

    Bunu yapmazsanız doInBackground() elde edersiniz.

    Nasıl yapılır?

    1. AsyncTask kullanırken, görünümü ViewRootImpl$CalledFromWrongThreadException yönteminden güncelleyin
    2. Veya onPostExecute() yöntemini arayın ve runOnUiThread() yönteminin içindeki görünümü güncelleyin.
    15
    2017-05-23 12: 10: 45Z

    Yukarıda büyük bir çözüm havuzu olmasına rağmen, hiç kimse run()’dan bahsetmedi: https://github.com/koush/iyon

    Ayrıca, kullanımında eşzamansız ve çok basittir :

     com.koushikdutta.ion     
    10
    2015-02-17 10: 31: 31Z

    Yeni

    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
        }
    });
    
    ve AsyncTask çözümleri zaten açıklanmıştır.

    Thread, kısa işlemler için ideal olarak kullanılmalıdır. AsyncTask normal Android için tercih edilmez.

    HandlerThread ve İşleyici

    HandlerThread

      

    Lüper olan yeni bir iş parçacığı başlatmak için kullanışlı bir sınıf. Looper daha sonra işleyici sınıfları oluşturmak için kullanılabilir. Thread’un hala aranması gerektiğini unutmayın.

    Handler:

      

    İşleyici, bir iş parçacığının MessageQueue ile ilişkilendirilmiş Message ve Runnable nesneleri göndermenizi ve işlemenizi sağlar. Her bir İşleyici örneği, tek bir iş parçacığı ve bu iş parçacığının ileti kuyruğuyla ilişkilendirilir. Yeni bir İşleyici oluşturduğunuzda, onu oluşturan iş parçacığının iş parçacığı /ileti sırasına bağlanır - bu noktadan itibaren, iletiler ve çalıştırılabilir iletiler iletinin dışına çıkar ve iletiden çıktıkça yürütülür sıra.

    Çözüm:

    1. start() Oluştur

    2. HandlerThread’da start()’u arayın

    3. HandlerThread’dan Handler’u alarak Looper’u oluşturun

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

    5. Runnable görevini Runnable'a gönder

    Handler adresli örnek kod pasajı

     NetworkOnMainThreadException

    Bu yaklaşımı kullanmanın avantajları:

    1. Her ağ işlemi için yeni
      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);
      
      oluşturmak pahalıdır. Thread/AsyncTask bir sonraki Ağ operasyonları için imha edilecek ve yeniden oluşturulacak. Ancak, Thread/AsyncTask ve Handler yaklaşımıyla, birçok ağ işlemini (Çalıştırılabilir görevler olarak) tekli olarak gönderebilirsiniz.HandlerThread kullanarak HandlerThread.
    9
    2017-11-05 04: 41: 03Z
    1. Bu doğru cevap olacaktır.
      2019-01-19 17: 33: 30Z

    Handler’u boşaltmak ve ANR , NetworkOnMainThreadException , IllegalStateException (ör. Potansiyel olarak kilitlenebileceğinden ana iş parçasındaki veritabanına erişilemiyor UI uzun süredir).

    Duruma göre seçmeniz gereken bazı yaklaşımlar var

    Java Konu veya Android HandlerThread

      

    Java iş parçacıkları yalnızca bir defalık kullanımdır ve çalışma yöntemini yürüttükten sonra ölür.

         

    HandlerThread, ilmek yapıcı olan yeni bir konu başlatmak için kullanışlı bir sınıftır.

    AsyncTask

      

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

    İplik havuzu uygulaması ThreadPoolExecutor , ZamanlanmışBaşlangıçPolosu Ekspresi ...

      

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

         

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

    FutureTask

      

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

    AsyncTaskLoaders

      

    AsyncTaskLoaders, AsyncTask'a özgü birçok sorunu çözdükçe

    IntentService

      

    Bu, Android'de uzun süredir devam eden işlemlerin varsayılan tercihidir, iyi bir örnek, büyük dosyaları yüklemek veya indirmek olabilir. Yükleme ve indirme, kullanıcı uygulamadan çıksa bile devam edebilir ve bu görevler devam ederken kullanıcının uygulamayı kullanmasını kesinlikle engellemek istemezsiniz.

    JobScheduler

      

    Etkili bir şekilde, Hizmeti ne zaman çalıştırmanız gerektiğine ilişkin kriterlerinizi belirten JobInfo.Builder'ı kullanarak bir Hizmet oluşturmanız ve bir iş oluşturmanız gerekir.

    RxJava

      

    Gözlenebilir dizileri kullanarak eşzamansız ve olaya dayalı programları oluşturmak için kitaplık.

    Coroutines (Kotlin)

      

    Asıl özü, eşzamansız kodun eşzamanlı gibi görünmesini sağlar

    Daha fazla buradan okuyun:
    Android'de zaman uyumsuz işlem yapmanın ve saymanın 8 yolu
    Android Ağ Erişiminin Gelişimi
    Android'de İplik Havuzu Kullanma
    Konuları ve Özel Hizmetleri Yönetme

        
    9
    2019-03-21 11: 15: 09Z
    1. Benim için çalıştım ... AsyncTask'ı yoğun kullandım, ancak bir görev diğerini çalıştırırken bekleyecek. Bunu çözmek istiyorum. Şimdi executeeonexecutor ile çalışıyor. Düşük bellek aygıtlarında nasıl davranacağını görelim.
      2018-03-25 05: 46: 40Z
    2. Lütfen yönteme bir göz atın: asyncTask.executeOnExecutor (AsyncTask.THREAD_POOL_EXECUTOR, params); görevinizi aynı anda yürütmek için
      2018-03-25 07: 52: 16Z

    main thread, bu soruna bir başka daha iyi alternatif ve bizi iş parçacığı yaratma ve Android UI iş parçacığıyla ilgili sonuçlar gönderme konusunda zorluklardan kurtarıyor. Sadece hangi görevlerin yerine getirilmesi gerektiğini ve her şeyin dahili olarak ele alınması gerektiğini belirtmemiz gerekiyor.

     RxAndroid
    1. 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);
          }
      });
      
      'u belirterek, RxAndroid (Schedulers.io())'u farklı bir iş parçacığında çalıştıracak.
    2. getFavoriteMusicShows()'u kullanarak, UI iş parçacığında bu Gözlemlenebilir'i gözlemlemek istiyoruz, yani AndroidSchedulers.mainThread() geri arama işlemimizin UI iş parçacığında çağrılmasını istiyoruz

    8
    2017-10-10 07: 52: 47Z

    Bu işe yarıyor. Dr.Luiji'nin cevabını biraz daha basitleştirdi.

     onNext()     
    7
    2015-02-13 23: 10: 17Z

    Android'de ağ işlemleri ana iş parçacığında çalıştırılamaz. Ağ işlemlerini yapmak için Thread, AsyncTask (kısa süreli görevler), Servis (uzun süreli görevler) kullanabilirsiniz.

        
    7
    2016-06-25 09: 32: 51Z

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

        
    7
    2016-06-25 09: 35: 31Z

    Android'deki UI iş parçacığında ağ işlemlerini gerçekleştirmenize izin verilmiyor. API isteği gönderme, bir URL'den resim indirme, vb. Gibi AsyncTask'in geri çağırma yöntemlerini kullanma gibi ağla ilgili işlemleri gerçekleştirmek için AsyncTask sınıfını kullanmanız gerekecek, onPostExecute anlamını verebilirsiniz ve UI iş parçacığında olacaksınız. UI'yi web hizmetindeki verilerle veya bunun gibi bir şeyle doldurabilir.

    Örnek: Bir URL’den resim indirmek istediğinizi varsayalım: https: //www.samplewebsite.com/sampleimage.jpg

    AsyncTask kullanarak çözüm:  sırasıyla.

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

    Not: Android bildirim dosyasına İnternet iznini eklemeyi unutmayın. Bir cazibe gibi çalışacak. :)

        
    6
    2016-06-25 09: 39: 03Z
        public class MyDownloader extends AsyncTask<String,Void,Bitmap>
        {
            @Override
            protected void onPreExecute() {
                // Show progress dialog
                super.onPreExecute();
            }
    
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                //Populate Ui
                super.onPostExecute(bitmap);
            }
    
            @Override
            protected Bitmap doInBackground(String... params) {
                // Open URL connection read bitmaps and return form here
                return result;
            }
    
            @Override
            protected void onProgressUpdate(Void... values) {
                // Show progress update
                super.onProgressUpdate(values);
            }
    
    
        }
    }
    
kaynak yerleştirildi İşte