it-swarm.com.de

Wie kann ich Android.os.NetworkOnMainThreadException beheben?

Beim Ausführen meines Android-Projekts für RssReader ist ein Fehler aufgetreten. 

Code:

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

Und es zeigt den folgenden Fehler:

Android.os.NetworkOnMainThreadException

Wie kann ich dieses Problem beheben?

2137
bejoy george

Diese Ausnahme wird ausgelöst, wenn eine Anwendung versucht, eine Netzwerkoperation in ihrem Haupt-Thread auszuführen. Führen Sie Ihren Code in AsyncTask aus:

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

So führen Sie die Aufgabe aus:

In MainActivity.Java-Datei können Sie diese Zeile innerhalb Ihrer oncreate()-Methode hinzufügen

new RetrieveFeedTask().execute(urlToRssFeed);

Vergessen Sie nicht, dies zu AndroidManifest.xml-Datei hinzuzufügen:

<uses-permission Android:name="Android.permission.INTERNET"/>
2367
michael

Sie sollten fast immer Netzwerkoperationen in einem Thread oder als asynchrone Task ausführen.

Aber es ist ist möglich, diese Einschränkung aufzuheben, und Sie überschreiben das Standardverhalten, wenn Sie bereit sind, die Konsequenzen zu akzeptieren.

Hinzufügen:

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

StrictMode.setThreadPolicy(policy); 

In deiner Klasse,

und

FÜGEN Sie diese Berechtigung in die Datei Android manifest.xml hinzu:

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

Folgen:

Ihre App reagiert nicht mehr und reagiert nicht mehr, der Benutzer nimmt die Langsamkeit wahr und muss einen Force Kill ausführen. Sie riskieren, dass der Aktivitätsmanager Ihre App beendet und dem Benutzer mitteilt, dass die App angehalten wurde.

Android hat einige gute Tipps für gute Programmierpraktiken, um die Reaktionsfähigkeit zu verbessern: http://developer.Android.com/reference/Android/os/NetworkOnMainThreadException.html

636
user1169115

Ich habe dieses Problem mit einer neuen Thread gelöst.

Thread thread = new Thread(new Runnable() {

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

thread.start(); 
381
Dr.Luiji

Die akzeptierte Antwort hat einige erhebliche Nachteile. Es ist nicht ratsam, AsyncTask für das Netzwerk zu verwenden, es sei denn, Sie wissen wirklich , was Sie tun. Einige der Nachteile sind:

  • AsyncTask-Objekte, die als nicht statische innere Klassen erstellt wurden, haben einen impliziten Verweis auf das einschließende Activity-Objekt, seinen Kontext und die gesamte View-Hierarchie, die von dieser Aktivität erstellt wurde. Durch diesen Verweis wird verhindert, dass die Aktivität überflüssig wird, bis die Hintergrundarbeit von AsyncTask abgeschlossen ist. Wenn die Verbindung des Benutzers langsam ist und/oder der Download groß ist, können diese Kurzzeitgedächtnislecks zu einem Problem werden - beispielsweise, wenn sich die Ausrichtung mehrmals ändert (und Sie die ausgeführten Aufgaben nicht abbrechen) oder der Benutzer navigiert weg von der Aktivität.
  • AsyncTask weist je nach der Plattform, auf der es ausgeführt wird, unterschiedliche Ausführungseigenschaften auf: Vor API-Ebene 4 werden AsyncTasks seriell auf einem einzelnen Hintergrundthread ausgeführt. Von API-Ebene 4 bis API-Ebene 10 werden AsyncTasks in einem Pool von bis zu 128 Threads ausgeführt. ab API-Level 11 wird AsyncTask seriell auf einem einzelnen Hintergrund-Thread ausgeführt (es sei denn, Sie verwenden die überladene executeOnExecutor -Methode und stellen einen alternativen Executor bereit). Code, der einwandfrei funktioniert, wenn er seriell unter ICS ausgeführt wird, kann bei gleichzeitiger Ausführung unter Gingerbread fehlerhaft sein, beispielsweise wenn Sie versehentlich Abhängigkeiten in der Ausführungsreihenfolge haben.

Wenn Sie kurzfristige Speicherverluste vermeiden möchten, über genau definierte Ausführungseigenschaften auf allen Plattformen verfügen und eine Basis für die Erstellung einer wirklich robusten Netzwerkverarbeitung haben möchten, sollten Sie Folgendes in Betracht ziehen:

  1. Verwenden einer Bibliothek, die dies für Sie erledigt - in diese Frage oder gibt es einen netten Vergleich der Netzwerkbibliotheken
  2. Verwenden Sie stattdessen Service oder IntentService, möglicherweise mit PendingIntent, um das Ergebnis über die onActivityResult -Methode der Aktivität zurückzugeben.

IntentService-Ansatz

Nachteile:

  • Mehr Code und Komplexität als AsyncTask, wenn auch nicht so viel, wie Sie vielleicht denken
  • Stellt Anforderungen in die Warteschlange und führt sie in einem einzelnen Hintergrundthread aus. Sie können dies einfach steuern, indem Sie IntentService durch eine entsprechende Service -Implementierung ersetzen, z. B. diese .
  • Ähm, ich kann momentan an keine anderen denken

Vorteile:

  • Vermeidet das Problem des Kurzzeitgedächtnisverlusts
  • Wenn Ihre Aktivität während des laufenden Netzwerkbetriebs neu gestartet wird, kann sie das Ergebnis des Downloads weiterhin über die Methode onActivityResult empfangen
  • Bessere Plattform als AsyncTask zum Erstellen und Wiederverwenden von robustem Netzwerkcode. Beispiel: Wenn Sie einen wichtigen Upload durchführen müssen, können Sie dies über AsyncTask in einem Activity tun. Wenn der Benutzer jedoch aus der App herausschaltet, um einen Anruf entgegenzunehmen, kann das System kann die App beenden, bevor der Upload abgeschlossen ist. Es ist weniger wahrscheinlich , eine Anwendung mit einem aktiven Service zu beenden.
  • Wenn Sie Ihre eigene parallele Version von IntentService verwenden (wie die oben verlinkte), können Sie den Grad der Parallelität über Executor steuern.

Implementierungszusammenfassung

Sie können ein IntentService implementieren, um Downloads auf einem einzelnen Hintergrund-Thread ganz einfach durchzuführen.

Schritt 1: Erstellen Sie ein IntentService, um den Download durchzuführen. Sie können ihm über Intent Extras mitteilen, was er herunterladen soll, und ihm ein PendingIntent übergeben, um das Ergebnis an Activity zurückzugeben:

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

Schritt 2: Registrieren Sie den Service im Manifest:

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

Schritt 3: Rufen Sie den Service über die Aktivität auf und übergeben Sie ein PendingResult-Objekt, mit dem der Service das Ergebnis zurückgibt:

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

Schritt 4: Behandeln Sie das Ergebnis in onActivityResult:

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

Ein Github-Projekt mit einem vollständigen funktionierenden Android-Studio/Gradle-Projekt ist verfügbar hier .

150
Stevie

Sie können network I/O nicht für den UI-Thread auf Honeycomb ausführen. Technisch ist es möglich auf früheren Versionen von Android, aber es ist eine wirklich schlechte Idee, da dies dazu führt, dass Ihre App nicht mehr reagiert und dazu führen kann Das Betriebssystem bringt Ihre App um, weil sie sich schlecht benommen hat. Sie müssen einen Hintergrundprozess ausführen oder AsyncTask verwenden, um Ihre Netzwerktransaktion für einen Hintergrundthread auszuführen.

Es gibt einen Artikel über Painless Threading auf der Android -Entwicklerseite, der eine gute Einführung in dieses Thema bietet und Ihnen eine viel bessere Antworttiefe liefert, als es realistisch sein kann hier zur Verfügung gestellt.

140
Mark Allison
  1. Verwenden Sie nicht strictMode (nur im Debug-Modus)
  2. Ändern Sie die SDK-Version nicht
  3. Verwenden Sie keinen separaten Thread

Verwenden Sie Service oder AsyncTask

Siehe auch Stack Overflow-Frage:

Android.os.NetworkOnMainThreadException sendet eine E-Mail von Android

67
venergiac

Führen Sie die Netzwerkaktionen in einem anderen Thread aus

Zum Beispiel:

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

Und fügen Sie dies zu AndroidManifest.xml hinzu 

<uses-permission Android:name="Android.permission.INTERNET"/>
61
henry4343

Sie deaktivieren den strikten Modus mit folgendem Code:

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

Dies wird nicht empfohlen: Verwenden Sie die AsyncTask-Schnittstelle.

Vollständiger Code für beide Methoden

52
Sandeep

Netzwerkbasierte Vorgänge können nicht im Hauptthread ausgeführt werden. Sie müssen alle netzwerkbasierten Aufgaben in einem untergeordneten Thread ausführen oder AsyncTask implementieren.

So führen Sie eine Aufgabe in einem untergeordneten Thread aus:

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

Geben Sie Ihren Code ein:

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

Oder:

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

Die Verwendung von Android Annotations ist eine Option. Sie können einfach eine beliebige Methode in einem Hintergrund-Thread ausführen:

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

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

Es ist zu beachten, dass es zwar Vorteile in Bezug auf Einfachheit und Lesbarkeit bietet, aber auch Nachteile hat. 

40
Oleksiy

Dies geschieht in Android 3.0 und höher. Ab Android 3.0 und höher wurde die Verwendung von Netzwerkvorgängen (Funktionen, die auf das Internet zugreifen) eingeschränkt, die im Haupt-Thread/UI-Thread ausgeführt werden (was aus Ihren On-Create- und Resume-Methoden in der Aktivität entsteht).

Dies dient dazu, die Verwendung separater Threads für den Netzwerkbetrieb zu fördern. Unter AsyncTask finden Sie weitere Informationen zur richtigen Durchführung von Netzwerkaktivitäten.

39
raihan ahmed

Sie sollten keine zeitaufwendigen Aufgaben im Hauptthread (UI-Thread) ausführen, wie etwa Netzwerkoperationen, Datei-E/A- oder SQLite-Datenbankoperationen. Für diese Art von Vorgang sollten Sie also einen Arbeitsthread erstellen. Das Problem ist jedoch, dass Sie keine UI-bezogenen Vorgänge von Ihrem Arbeitsthread aus direkt ausführen können. Dazu müssen Sie Handler verwenden und die Message übergeben. 

Um all diese Dinge zu vereinfachen, bietet Android verschiedene Möglichkeiten, wie AsyncTask, AsyncTaskLoader, CursorLoader oder IntentService. So können Sie diese je nach Ihren Anforderungen verwenden.

35
Kapil Vats

Der Fehler ist auf lange ausgeführte Operationen im Haupt-Thread zurückzuführen. Sie können das Problem leicht beheben, indem Sie AsynTask oder Thread verwenden. Sie können diese Bibliothek AsyncHTTPClient zur besseren Handhabung auschecken. 

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
    }
});
34
Ashwin S Ashok

Die Top Antwort von spektom funktioniert perfekt.

Wenn Sie die AsyncTask-Inline schreiben und sich nicht als Klasse erweitern, und wenn Sie eine Antwort aus der AsyncTask erhalten müssen, können Sie die get()-Methode wie folgt verwenden.

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

(Aus seinem Beispiel.)

34
sivag1

Dies wird nur für Anwendungen ausgelöst, die auf das Honeycomb SDK oder höher abzielen. Anwendungen, die auf frühere SDK-Versionen abzielen, dürfen in ihren Hauptereignisschleifen-Threads vernetzen.

Der Fehler ist die SDK-Warnung!

28
perry

Für mich war es das:

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

Das Gerät, auf dem ich meine App getestet habe, war 4.1.2, also SDK Version 16!

Stellen Sie sicher, dass die Zielversion mit Ihrer Android-Zielbibliothek übereinstimmt. Wenn Sie sich nicht sicher sind, was Ihre Zielbibliothek ist, klicken Sie mit der rechten Maustaste auf Project -> Build Path -> Android . Dies sollte das angekreuzte sein.

Fügen Sie, wie andere bereits erwähnt haben, die richtigen Zugriffsrechte für das Internet hinzu:

<uses-permission Android:name="Android.permission.INTERNET"/>
23
rharvey

Um etwas explizit auszusprechen:

Der Haupt-Thread ist im Wesentlichen der UI-Thread.

Wenn Sie also sagen, dass Sie keine Netzwerkoperationen im Hauptthread ausführen können, bedeutet das, dass Sie keine Netzwerkoperationen im UI-Thread ausführen können, dh Sie können keine Netzwerkoperationen in einem *runOnUiThread(new Runnable() { ... }*-Block in einem anderen Thread ausführen.

(Ich hatte gerade einen langen, kratzenden Moment, als ich versuchte herauszufinden, warum ich diesen Fehler an einem anderen Ort als meinem Haupt-Thread gefunden hatte. Dies war der Grund; dieser Thread hat geholfen; und hoffentlich hilft dieser Kommentar jemand anderem.)

21
Novak

Diese Ausnahmebedingung tritt aufgrund schwerer Aufgaben auf, die für den Haupt-Thread ausgeführt werden, wenn diese durchführende Aufgabe zu viel Zeit benötigt.

Um dies zu vermeiden, können wir es mit Threads oder Executoren behandeln.

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

Es gibt bereits viele gute Antworten auf diese Frage, aber seitdem diese Antworten veröffentlicht wurden, sind viele gute Bibliotheken herausgekommen. Dies ist als eine Art Neuling-Leitfaden gedacht.

Ich werde mehrere Anwendungsfälle für die Durchführung von Netzwerkoperationen und eine Lösung oder zwei für jede behandeln.

ReST über HTTP

Typischerweise Json, kann XML oder etwas anderes sein

Voller API-Zugriff

Angenommen, Sie schreiben eine App, mit der Benutzer Aktienkurse, Zinssätze und Wechselkurse verfolgen können. Sie finden eine Json-API, die ungefähr so ​​aussieht:

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)

Nachrüstung von Square

Dies ist eine ausgezeichnete Wahl für eine API mit mehreren Endpunkten und ermöglicht es Ihnen, die ReST-Endpunkte zu deklarieren, anstatt sie einzeln wie bei anderen Bibliotheken wie ion oder Volley zu codieren. (Website: http://square.github.io/retrofit/ )

Wie verwenden Sie es mit der Finanzen-API?

build.gradle

Fügen Sie diese Zeilen zu Ihrer Modulebene buid.gradle hinzu:

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

FinancesFragment Snippet

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

Wenn für Ihre API der Versand eines API-Schlüssels oder eines anderen Headers wie eines Benutzertokens usw. erforderlich ist, ist dies mit Retrofit ganz einfach (Details finden Sie in dieser fantastischen Antwort: https: // stackoverflow. com/a/42899766/1024412 ).

Einmaliger Zugriff auf die ReST-API

Angenommen, Sie erstellen eine "Stimmungswetter" -App, die den GPS-Standort des Benutzers abfragt, die aktuelle Temperatur in diesem Bereich überprüft und ihm die Stimmung mitteilt. Dieser App-Typ muss keine API-Endpunkte deklarieren. Es muss nur in der Lage sein, auf einen API-Endpunkt zuzugreifen.

Ion

Dies ist eine großartige Bibliothek für diese Art von Zugriff.

Bitte lesen Sie die großartige Antwort von msysmilu ( https://stackoverflow.com/a/28559884/1024412 )

Laden Sie Bilder über HTTP

Volley

Volley kann auch für ReST-APIs verwendet werden, aber aufgrund des komplizierteren Setups bevorzuge ich Retrofit von Square wie oben ( http://square.github.io/retrofit/ )

Angenommen, Sie erstellen eine Social-Networking-App und möchten Profilbilder von Freunden laden.

build.gradle

Fügen Sie diese Zeile Ihrem Modullevel buid.gradle hinzu:

implementation 'com.Android.volley:volley:1.0.0'

ImageFetch.Java

Volley erfordert mehr Setup als Retrofit. Sie müssen eine Klasse wie diese erstellen, um eine RequestQueue, einen ImageLoader und einen ImageCache einzurichten, aber es ist nicht so schlimm:

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

Fügen Sie Ihrer Layout-XML-Datei Folgendes hinzu, um ein Bild hinzuzufügen:

<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

Fügen Sie der onCreate-Methode (Fragment, Activity) oder dem Konstruktor (Dialog) den folgenden Code hinzu:

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

Picasso

Eine weitere hervorragende Bibliothek von Square. Auf der Website finden Sie einige gute Beispiele: http://square.github.io/picasso/

16
KG6ZVP

Verwenden Sie dies in Ihrer Aktivität

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

In einfachen Worten

VERWENDEN SIE KEIN NETZWERK IM UI-GEWINDE

Wenn Sie beispielsweise eine HTTP-Anforderung ausführen, handelt es sich um eine Netzwerkaktion.

Lösung:

  1. Sie müssen einen neuen Thread erstellen
  2. Oder use AsyncTask-Klasse

Weg:

Legen Sie alle Ihre Werke hinein

  1. run() Methode des neuen Threads
  2. OderdoInBackground()-Methode der AsyncTask-Klasse.

Aber:

Wenn Sie etwas von Network response erhalten und es in Ihrer Ansicht anzeigen möchten (wie z. B. eine Antwortnachricht in TextView anzeigen), müssen Sie zum UI - Thread zurückkehren.

Wenn Sie es nicht tun, erhalten Sie ViewRootImpl$CalledFromWrongThreadException.

Wie man?

  1. Aktualisieren Sie bei Verwendung von AsyncTask die Ansicht von der onPostExecute()-Methode
  2. Oder Aufruf runOnUiThread() -Methode und Aktualisierungsansicht innerhalb der run()-Methode.
14
Nabin

Obwohl es oben einen riesigen Lösungspool gibt, hat niemand com.koushikdutta.ion: https://github.com/koush/ion erwähnt.

Es ist auch asynchronous und sehr einfach zu verwenden:

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
msysmilu

Neue Thread- und AsyncTask -Lösungen wurden bereits erläutert.

AsyncTask sollte idealerweise für kurze Operationen verwendet werden. Normal Thread ist für Android nicht vorzuziehen. 

Schauen Sie sich die alternative Lösung mit HandlerThread und Handler an.

HandlerThread

Praktische Klasse zum Starten eines neuen Threads mit einem Looper. Der Looper kann dann zum Erstellen von Handler-Klassen verwendet werden. Beachten Sie, dass start() noch aufgerufen werden muss.

Handler:

Mit einem Handler können Sie Message- und Runnable-Objekte senden und verarbeiten, die MessageQueue eines Threads zugeordnet sind. Jede Handler-Instanz ist einem einzelnen Thread und der Nachrichtenwarteschlange dieses Threads zugeordnet. Wenn Sie einen neuen Handler erstellen, ist er an die Thread-/Nachrichtenwarteschlange des Threads gebunden, der ihn erstellt. Von diesem Zeitpunkt an liefert er Nachrichten und ausführbare Dateien an diese Nachrichtenwarteschlange und führt sie aus, sobald sie aus der Nachricht herauskommen Warteschlange.

Lösung:

  1. HandlerThread erstellen

  2. Aufruf von start() bei HandlerThread

  3. Erstellen Sie Handler, indem Sie Looper von HanlerThread abrufen.

  4. Betten Sie Ihren Code zum Netzwerkbetrieb in das Objekt Runnable ein

  5. Runnable-Aufgabe an Handler übergeben

Beispiel-Codeausschnitt, der NetworkOnMainThreadException adressiert

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

Vorteile dieses Ansatzes:

  1. Das Erstellen eines neuen Thread/AsyncTask für jeden Netzwerkbetrieb ist teuer. Der Thread/AsyncTask wird gelöscht und für den nächsten Netzwerkbetrieb neu erstellt. Mit dem Ansatz "Handler" und "HandlerThread" können Sie jedoch viele Netzwerkvorgänge (als ausführbare Aufgaben) an HandlerThread mit Handler übergeben. 
8
Ravindra babu

Der Zugriff auf Netzwerkressourcen vom Hauptthread (UI) verursacht diese Ausnahme. Verwenden Sie einen separaten Thread oder eine AsyncTask für den Zugriff auf eine Netzwerkressource, um dieses Problem zu vermeiden.

Unter Android können Netzwerkvorgänge nicht im Hauptthread ausgeführt werden. Sie können Thread, AsyncTask (kurz ausgeführte Aufgaben) und Service (lang andauernde Aufgaben) verwenden, um Netzwerkvorgänge auszuführen.

Das funktioniert. Ich habe gerade die Antwort von Dr. Luiji etwas einfacher gemacht.

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

RxAndroid ist eine weitere bessere Alternative zu diesem Problem und erspart uns die Mühe, Threads zu erstellen und dann Ergebnisse im Android-UI-Thread zu veröffentlichen. Wir müssen nur Threads angeben, an denen Aufgaben ausgeführt werden müssen und alles intern erledigt wird.

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. Durch Angabe von (Schedulers.io()) führt RxAndroid getFavoriteMusicShows() in einem anderen Thread aus.

  2. Mit AndroidSchedulers.mainThread() wollen wir dieses Observable im UI-Thread beobachten, d. H. Wir möchten, dass unser onNext()-Callback im UI-Thread aufgerufen wird

7
Shinoo Goyal

Sie können einen Teil Ihres Codes in einen anderen Thread verschieben, um den main thread auszulagern und zu vermeiden, dass Sie ANR , NetworkOnMainThreadException , IllegalStateException erhalten (z. B. seit dem Zugriff auf die Datenbank im Hauptthread nicht kann die Benutzeroberfläche möglicherweise für einen längeren Zeitraum sperren). 

Es gibt einige Ansätze, die Sie abhängig von der Situation wählen sollten

Java Thread oder Android HandlerThread

Java-Threads werden nur einmal verwendet und sterben nach Ausführung der Run-Methode.

HandlerThread ist eine praktische Klasse zum Starten eines neuen Threads, der einen Looper hat.

AsyncTask

AsyncTask ist eine Hilfsklasse um Thread und Handler und ist kein generisches Threading-Framework. AsyncTasks sollten idealerweise für kurze Operationen (höchstens einige Sekunden) verwendet werden. Wenn Sie Threads über einen längeren Zeitraum laufen lassen müssen, wird dringend empfohlen, die verschiedenen APIs des Java.util.concurrent-Pakets zu verwenden, wie z Executor, ThreadPoolExecutor und FutureTask.

Threadpool-Implementierung ThreadPoolExecutor , ScheduledThreadPoolExecutor ...

ThreadPoolExecutor-Klasse, die den ExecutorService implementiert, der eine Feinsteuerung des Thread-Pools ermöglicht (z. B. Kernpoolgröße, maximale Poolgröße, Keep-Alive-Zeit usw.)

ScheduledThreadPoolExecutor - eine Klasse, die ThreadPoolExecutor erweitert. Es kann Aufgaben nach einer bestimmten Verzögerung oder in regelmäßigen Abständen planen.

FutureTask

FutureTask führt eine asynchrone Verarbeitung durch. Wenn das Ergebnis jedoch noch nicht fertig ist oder die Verarbeitung noch nicht abgeschlossen ist, wird der Aufruf von get () den Thread blockieren 

AsyncTaskLoaders

AsyncTaskLoaders, da sie viele Probleme lösen, die mit AsyncTask einhergehen

IntentService

Dies ist die defacto Wahl für die langwierige Verarbeitung unter Android. Ein gutes Beispiel wäre das Hochladen oder Herunterladen großer Dateien. Das Hochladen und Herunterladen kann fortgesetzt werden, auch wenn der Benutzer die App beendet und Sie den Benutzer sicher nicht daran hindern möchten, die App während der Ausführung dieser Aufgaben zu verwenden.

JobScheduler

Sie müssen effektiv einen Dienst erstellen und einen Job mit JobInfo.Builder erstellen, der Ihre Kriterien für die Ausführung des Dienstes angibt.

RxJava

Bibliothek zum Erstellen asynchroner und ereignisbasierter Programme unter Verwendung beobachtbarer Sequenzen.

Coroutinen (Kotlin)

Das Hauptmerkmal ist, dass asynchroner Code so aussieht wie synchron

Lesen Sie hier mehr:
8 Möglichkeiten, asynchrone Verarbeitung in Android durchzuführen und zu zählen
Die Entwicklung des Android-Netzwerkzugriffs
Verwenden eines Thread-Pools in Android

6
yoAlex5

Sie dürfen keine Netzwerkoperationen im UI-Thread unter Android implementieren. Sie müssen die AsyncTask-Klasse verwenden, um netzwerkbezogene Vorgänge auszuführen, z. B. das Senden einer API-Anfrage, das Herunterladen eines Bildes von einer URL usw. und die Verwendung von Callback-Methoden von AsyncTask. Sie können ein Ergebnis in onPostExecute menthod abrufen und Sie befinden sich im UI-Thread kann die Benutzeroberfläche mit Daten aus dem Webdienst oder ähnlichem füllen.

Beispiel: Angenommen, Sie möchten ein Bild von einer URL herunterladen: https://www.samplewebsite.com/sampleimage.jpg

Lösung mit AsyncTask: sind jeweils.

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


    }
}

Hinweis: Vergessen Sie nicht, die Internet-Berechtigung in der Android-Manifestdatei hinzuzufügen. Es wird wie ein Zauber wirken. :)

6
Krishna

Es gibt eine weitere sehr bequeme Möglichkeit, dieses Problem zu lösen: Verwenden Sie die Parallelitätsfunktionen von rxJava. Sie können jede Aufgabe im Hintergrund ausführen und die Ergebnisse auf sehr bequeme Weise im Haupt-Thread veröffentlichen, sodass diese Ergebnisse an die Verarbeitungskette übergeben werden.

Der erste bestätigte Antworthinweis ist die Verwendung von AsynTask. Ja, dies ist eine Lösung, die aber heutzutage veraltet ist, weil es neue Werkzeuge gibt.

String getUrl() {
    return "SomeUrl";
}

private Object makeCallParseResponse(String url) {
    return null;
    //
}

private void processResponse(Object o) {

}

Die getUrl-Methode stellt die URL-Adresse bereit und wird im Hauptthread ausgeführt.

makeCallParseResponse (..) - führt die eigentliche Arbeit aus

processResponse (..) - behandelt das Ergebnis im Haupt-Thread.

Der Code für die asynchrone Ausführung sieht wie folgt aus:

rx.Observable.defer(new Func0<rx.Observable<String>>() {
    @Override
    public rx.Observable<String> call() {
        return rx.Observable.just(getUrl());
    }
})
    .subscribeOn(Schedulers.io())
    .observeOn(Schedulers.io())
    .map(new Func1<String, Object>() {
        @Override
        public Object call(final String s) {
            return makeCallParseResponse(s);
        }
    })
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Object>() {
        @Override
        public void call(Object o) {
             processResponse(o);
        }
    },
    new Action1<Throwable>() {
        @Override
        public void call(Throwable throwable) {
            // Process error here, it will be posted on
            // the main thread
        }
    });

Im Vergleich zu AsyncTask ermöglicht diese Methode das Wechseln von Schedulern in beliebiger Anzahl (z. B. Abrufen von Daten in einem Scheduler und Verarbeiten dieser Daten in einem anderen) (z. B. Scheduler.computation ()). Sie können auch eigene Scheduler definieren.

Um diese Bibliothek zu verwenden, fügen Sie folgende Zeilen in Ihre build.gradle -Datei ein:

   compile 'io.reactivex:rxjava:1.1.5'
   compile 'io.reactivex:rxandroid:1.2.0'

Die letzte Abhängigkeit umfasst die Unterstützung für den .mainThread () - Scheduler.

Es gibt ein hervorragendes E-Book für RX-Java .

6
Alex Shutov

Sie können entweder KOTLIN und ANKO verwenden. 

Kotlin ist die neue Amtssprache für Android mehr darüber finden Sie hier https://kotlinlang.org/docs/tutorials/kotlin-Android.html

Anko unterstützte Bibliothek für Kotlin in Android, einige Dokumente hier https://github.com/Kotlin/anko

Die Lösung ist wirklich nützlich und enthält nur wenige Codezeilen von @AntonioLeiva https://antonioleiva.com/anko-background-kotlin-Android/

doAsync {
    var result = runLongTask()
    uiThread {
        toast(result)
    }
}

So einfach es ist, tritt NetworkOnMainThread auf, wenn Sie einen Hintergrundjob für UI Thread ausführen. Sie müssen also longTask job im Hintergrund ausführen. Sie können dies mit dieser Methode und Kotlin mit Anko in Ihrer Android-App tun.

5
J.D.1731

Ich habe dieses Problem auf einfache Weise gelöst ...

Ich habe nach oncreateStrictMode.enableDefaults(); hinzugefügt und dieses Problem gelöst.

Oder

verwenden Sie Service oder AsyncTask, um das Problem zu lösen

Hinweis:

Do not change SDK version
Do not use a separate thread

Für mehr, check this .

4

Diese Ausnahmebedingung wird ausgelöst, wenn eine Anwendung versucht, einen Netzwerkvorgang in ihrem Haupt-Thread auszuführen. Wenn Ihre Aufgabe länger als fünf Sekunden dauerte, wird ein Kraftaufwand benötigt.

Führen Sie Ihren Code in AsyncTask aus:

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

    protected RSSFeed doInBackground(String... urls) {
       // TODO: Connect
    }

    protected void onPostExecute(RSSFeed feed) {
        // TODO: Check this.exception
        // TODO: Do something with the feed
    }
}
4

Android.os.NetworkOnMainThreadException wird ausgelöst, wenn Netzwerkvorgänge im Hauptthread ausgeführt werden. Sie sollten dies in AsyncTask tun, um diese Ausnahme zu entfernen. Schreib es so:

    new AsyncTask<Void,String,String>(){

        @Override
        protected Void doInBackground(Void... params) {
            // Perform your network operation.
            // Get JSON or XML string from the server.
            // Store in a local variable (say response) and return.
            return response;
        }

        protected void onPostExecute(String results){
            // Response returned by doInBackGround() will be received
            // by onPostExecute(String results).
            // Now manipulate your jason/xml String(results).
        }

    }.execute();
}
3
Mansuu....

Wir können RxJava auch verwenden, um Netzwerkoperationen in einen Hintergrundthread zu verschieben. Und es ist auch ziemlich einfach.

webService.doSomething(someData)
          .subscribeOn(Schedulers.newThread())-- This for background thread
          .observeOn(AndroidSchedulers.mainThread()) -- for callback on UI              
          .subscribe(result -> resultText.setText("It worked!"),
              e -> handleError(e));

Sie können noch viel mehr mit RxJava machen. Hier finden Sie einige Links zu RxJava. Fühlen Sie sich frei zu graben. 

RxJava Async-Aufgabe in Android

http://blog.stablekernel.com/replace-asynctask-asynctaskloader-rx-observable-rxjava-Android-patterns/

3
bpr10

Der Haupt-Thread ist der UI-Thread, und Sie können keine Operation im Haupt-Thread ausführen, die die Benutzerinteraktion blockieren kann. Sie können dies auf zwei Arten lösen:

Erzwinge die Aufgabe im Haupt-Thread wie folgt

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

Oder erstellen Sie einen einfachen Handler und aktualisieren Sie den Haupt-Thread, wenn Sie möchten.

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

Um den Thread zu stoppen, verwenden Sie:

newHandler.removeCallbacks(runnable);

Weitere Informationen finden Sie hier: schmerzloses Einfädeln

3
Anonymous

Sie können dieses Problem auch beheben, indem Sie den strengen Modus mit dem folgenden Code verwenden. Es ist auch eine Alternative zur Lösung dieses Problems.

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

Die beste Vorgehensweise wäre jedoch die Verwendung von AsyncTask.

3
Himanshu

So beheben Sie Android.os.NetworkOnMainThreadException

Was ist NetworkOnMainThreadException:

In Android müssen alle UI-Vorgänge auf dem UI-Thread (Haupt-Thread) ausgeführt werden. Wenn wir Hintergrundoperationen oder einige Netzwerkoperationen im Hauptthread ausführen, besteht das Risiko, dass diese Ausnahme auftritt und die App nicht antwortet.

Wie man es repariert:

Um dieses Problem zu vermeiden, müssen Sie einen anderen Thread für Hintergrundoperationen oder Netzwerkoperationen verwenden, z. B. asyncTask und eine Bibliothek für Netzwerkoperationen wie Volley, AsyncHttp usw.

Die NetworkOnMainThread-Ausnahme tritt auf, weil Sie einige Netzwerkoperationen für den Standard-Thread, dh den UI-Thread, aufgerufen haben. Laut Android-Version Android 3 (Honeycomb), die nicht zulässig ist, sollten Sie den Netzwerkbetrieb außerhalb des Hauptthreads aufrufen.

Sie können AsyncTask, IntentService oder das Erstellen eines eigenen Threads und das Aufrufen der Laufmethode verwenden. Weitere Informationen hierzu finden Sie unter Verbindung zum Netzwerk herstellen.

1
BalaramNayak

Tun Sie dies im Hintergrund-Thread mit AsycTask

Java

class NetworkThread extends AsyncTask<String, Void, String> {

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

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

Rufen Sie an, wo immer Sie brauchen

new NetworkThread().execute("Your URL here");

Kotlin

internal class MyNetworkTask : AsyncTask<String, Void, RSSFeed>() {

    override fun doInBackground(vararg urls: String): RSSFeed? {
        try {
             // download
             // prepare RSSFeeds
             return RSSFeeds
         } catch (e: Exception) {
            //handle exception
            return null
        }
    }

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

Rufen Sie Kotlin an

MyNetworkTask().execute(url)
1
Vipul Prajapati

Sie können das Netzwerk nicht im Haupt- oder UI-Thread aufrufen. Unter Android gibt es zwei Möglichkeiten, wenn Sie ein Netzwerk anrufen möchten:

  1. Rufen Sie asynctask auf, um einen Hintergrundthread für die Netzwerkoperation auszuführen.
  2. Sie können einen eigenen ausführbaren Thread erstellen, um die Netzwerkoperation zu handhaben.

Persönlich bevorzuge ich Asynctask. Für weitere Informationen können Sie auf diesen Link verweisen.

1
Hossain Ahamed

Da Android an einem einzelnen Thread arbeitet, sollten Sie keine Netzwerkoperation für den Haupt-Thread ausführen. Es gibt verschiedene Möglichkeiten, dies zu vermeiden.

Gehen Sie folgendermaßen vor, um eine Netzwerkoperation durchzuführen

  • Asysnctask : Für kleine Operationen, die nicht viel Zeit benötigen.
  • Intent Service : Für Netzwerkbetrieb, der viel Zeit in Anspruch nimmt.
  • Verwenden Sie eine benutzerdefinierte Bibliothek wie Volley und Retrofit , um komplexe Netzwerkvorgänge auszuführen

Verwenden Sie niemals StrictMode.setThreadPolicy (policy) , da dies Ihre Benutzeroberfläche einfrieren wird und überhaupt keine gute Idee ist.

1
aks

Du kannst tatsächlich einen neuen Thread starten, ich hatte dieses Problem schon einmal und löste es so.

1
rObOtAndChalie

Kotlin-Version

internal class RetrieveFeedTask : AsyncTask<String, Void, RSSFeed>() {

    override fun doInBackground(vararg urls: String): RSSFeed? {

        try {
             // download
             // prepare RSSFeeds
             return RSSFeeds

         } catch (e: Exception) {

            //handle exception
            return null
        }
    }

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

Beispiel aufrufen,

RetrieveFeedTask().execute(url)
0

Sie können Kotlin-coroutines verwenden

 class YoutActivity : AppCompatActivity, CoroutineScope {

      override fun onCreate(...) {
         launch {  yourHeavyMethod() }
      }

      suspend fun yourHeavyMethod() {
         async{ yourNetworkCall() }.await()
         ...
         ...
      }

 } 

Du kannst this guide folgen. 

0
Santanu Sur

Ich hatte ein ähnliches Problem. Ich habe nur die folgende Methode zum Erstellen Ihrer Aktivität verwendet.

//allow strict mode
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

und es hat gut funktioniert.

0
Richard Kamere

Ab 2018 würde ich empfehlen, RxJava in Kotlin für den Netzwerkabruf zu verwenden. Ein einfaches Beispiel ist unten.

Single.fromCallable {
        // Your Network Fetching Code
        Network.fetchHttp(url) 
    }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe {
        // What you need to do with your result on the view 
        result -> view.updateScreen(result) 
    }
0
Elye

Verschiedene Optionen:

  1. verwenden Sie einen normalen Java-Run-Thread, um die Netzwerkaufgabe zu verarbeiten, und verwenden Sie runOnUIThread (), um die Benutzeroberfläche zu aktualisieren

  2. die Task intentservice/async kann verwendet werden, wenn Sie die Benutzeroberfläche aktualisieren möchten, nachdem Sie eine Antwort vom Netzwerk erhalten haben

0
Ashok Kumar

Führen Sie niemals lange laufende Arbeiten am UI-Thread durch. Diese lange laufende Arbeit kann die Kommunikation mit dem Server, Lesen/Schreiben auf Datei usw. sein. Diese Aufgaben sollten im Hintergrund-Thread sein, deshalb werden Service, AsyncTask, Threads erstellt. Sie können StrictMode deaktivieren, um einen Absturz zu verhindern, der jedoch nie empfohlen wird. 

Ich würde vorschlagen, dass Sie StrictMode atleast im Debug-Modus nutzen. Verwenden Sie den folgenden Code, um Protokolle aller Probleme abzurufen, die Ihre App im Haupt-Thread verlangsamen.

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build());

Sie können verschiedene Strafen festlegen - 

penaltyLog() // to print log
penaltyDeath() // This will crash you App(so costly penalty)
penaltyDialog() // Show alert when something went lazy on Main thread

Es gibt so viel über https://developer.Android.com/reference/Android/os/StrictMode.html

0
Rahul

Wenn Sie in Kotlin und Anko arbeiten, können Sie hinzufügen 

 doAsync {
   method()
}
0
Devix