2016-05-19 5 views
0

Ich verstehe, dass Netzwerkaufrufe und SQLite Zugriffe am besten durch Worker-Threads getan werden. In meinem Fall werden meine Netzwerkanrufe durch Okhttp erledigt und die SQLite wird durch einen einzelnen Arbeitsthread erledigt.Übersprungen 130 Frames, zu viel Arbeit auf dem Hauptthread

Also hier ist mein Problem. Ich habe eine Hauptaktivität, die alle Aktien enthält, die der Benutzer in einer Listenansicht gekauft hat. Jedes Mal, wenn diese neue Aktivität erstellt wird, durchläuft die Methode onCreate die Bestände in der Datenbank und aktualisiert sie einzeln und aktualisiert dann die Listenansicht.

Dies belastet natürlich den Hauptfaden zu sehr. Aber mein Problem ist, wie kann ich das besser gestalten? Im Moment habe ich so etwas wie dies im onCreate:

Thread t1 = new Thread(new Runnable{ 
    @Override 
    public void run(){ 
     // access sqlite 
     positionsArray = retrieveStocks(); 
    }  
}); 
t1.start(); 
t1.join(); //try catch omitted 

Thread t2 = new Thread(new Runnable{ 
    @Override 
    public void run(){ 
     // use Okhttp to get data 
     positionsArray = refreshStocks(); 
    }  
}); 
t1.start(); 
t2.join(); //try catch omitted 

adapter = new PositionsAdapter(this, positionsArray); 
listview.setAdapter(adapter); 

Das ist nicht das Problem weggehen nicht machen, weil der Haupt-Thread noch für t1 und t2 warten. Irgendwelche Designvorschläge, wie ich dieses Problem beheben kann?

+0

Ihr auf create-Methode ein Text „Laden“ sollte zu tun, während Sie für die Threads warten – RMalke

+0

Wie wäre es mit Loader zu vervollständigen? (Https://developer.android.com /reference/android/app/LoaderManager.html) Sie können zuerst den Ladetext (oder die zwischengespeicherten Daten) anzeigen und dann die Daten nach dem Laden aktualisieren. – chartsai

+0

Ja, aber ich überspringe immer noch über 130 Frames, ich bekomme immer noch die Warnung, dass zu viel Arbeit am Hauptthread erledigt ist. –

Antwort

1

Sie sollten nie thread.join() im ui-Thread aufrufen, da dies die App pausiert. Sie könnten eine Asynchron-Aufgabe verwenden diese AsyncTask Android example

ProgressDialog progress; 
private class DoNetworking extends AsyncTask<Void, Void, PosArray> { 

    @Override 
    protected PosArray doInBackground() { 
     positionsArray = retrieveStocks(); 
     positionsArray = refreshStocks(); 
     PosArray positionsArray; 
    } 

    @Override 
    protected void onPostExecute(PosArray positionsArray) { 
     adapter = new PositionsAdapter(this, positionsArray); 
     listview.setAdapter(adapter); 
     progress.dismiss(); 
    } 
} 
progress = ProgressDialog.show(this, "dialog title","dialog message", true); 
new DoNetworking().execute() 
+0

also, wenn ich Async-Task verwenden, um den Adapter festzulegen, würde der Haupt-Thread immer noch auf die Ergebnisse warten müssen, um zurück zu kommen? Würde der Hauptthread immer noch warten, bis die Listenansicht festgelegt wurde, bevor sie auf dem Bildschirm gezeichnet werden kann? –

+0

ja der Hauptbildschirm wird nicht aktualisiert, bis die Daten zurückkommen, aber der Bildschirm wird nicht eingefroren werden, wie Sie es hatten. Es ist Ihre Aufgabe, einen Fortschrittsbalken oder Fortschrittsdialog zu laden, während der Benutzer wartet. Iv hinzugefügt ein Beispiel für Sie –

+0

Ah, ok ich sehe, also lassen Sie mich das gerade, mit AsyncTask würde die Aktivität zu zeichnen Dinge ohne es blockiert, und es kann auf AsyncTask warten, solange es dauert? Würde auch Okhttp anrufen, um Netzwerkanrufe innerhalb von AsyncTask sinnvoll zu machen? –

Verwandte Themen