Configurazione di un ciclo in AsyncTask per recuperare l'iterazione successiva di una sequenza
-
29-10-2019 - |
Domanda
Sto scaricando diverse immagini e nomi da un Collection
e li sto applicando in un GridView
. Ho riscontrato alcuni problemi nel far funzionare correttamente il mio AsyncTask
. Devo restituire due valori diversi, un'immagine e un nome, da un URL. Al momento, posso scaricare correttamente tutto e applicare le informazioni al mio ImageView
e TextView
, ma il mio metodo per farlo funziona solo mentre lo chiamo nel mio Adapter
.
Problema:
Quando imposto il mio AsyncTask
per scaricare tutto, applica solo il primo valore della sequenza al Views
nella mia griglia. Quando registro "artistImages", stampa gli altri URL della sequenza un numero enorme di volte, non so perché questo accada, ma nessuno dei dati degli URL è effettivamente applicato nel mio Adapter
.
Cosa ho provato:
Ho provato a impostare un ciclo in doInBackground()
per eseguire il mio Iterator
n volte.
Ho provato a utilizzare un Boolean
per interrompere il mio iteratore prima che applichi i dati dal primo set nella sequenza a tutto il mio Views
.
Ho provato a impostare il mio Adapter
nel mio AsyncTask
.
Ho provato a impostare un nuovo AsyncTask
nel mio Adapter
, invece di creare una nuova classe.
Ho provato a impostare il mio ImageView
in onPostExecute()
e nel mio Adapter
.
Ho provato a utilizzare diversi parametri nel mio AsyncTask
.
Ho provato a impostare un AsyncTask
per il mio Views
, in modo che il mio Iterator
possa essere eseguito in modo funzionale e le immagini e il nome vengano applicati in modo asincrono.
Ho svolto molte ricerche sull'arresto del loop o AsyncTask
a un certo punto, sull'impostazione di AsyncTaks
in un GridView
o con un Adapter
e molte altre letture su Threads
, Handlers
e AsyncTask
in generale.
Tutti questi tentativi determinano solo il primo set della sequenza utilizzato o non viene scaricato e applicato nulla. Quindi, sto attraversando un periodo piuttosto difficile utilizzando il mio Iterator
nel mio AsyncTask
.
Questo è il codice che sto usando per scaricare le immagini e i nomi. Funziona fintanto che lo utilizzo all'interno del metodo getView
my Adapter
.
Utilizzato per scaricare immagini e nomi:
i++;
artistImage = Artist.getSimilar("Bon Iver", i, key);
new ArrayList<Artist>();
itr = artistImage.iterator();
while (itr.hasNext()) {
Artist temp = itr.next();
artistImages = ((ImageHolder) temp).getImageURL(ImageSize.MEGA);
artistName = ((MusicEntry) temp).getName();
}
Solo per mostrare cos'è tutto:
private Iterator<Artist> itr;
private Collection<Artist> artistImage;
private String artistImages = null;
private String artistName = null;
private int i = 0;
AsyncTask: lo chiamo in getView
del mio Adapter
. new loadImages().execute()
public class loadImages extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
try {
Thread.sleep(50);
for (int i = 0; i <= 10; i++) {
artistImage = Artist.getSimilar("Bon Iver", i, key);
new ArrayList<Artist>();
itr = artistImage.iterator();
while (itr.hasNext()) {
Artist temp = itr.next();
artistImages = ((ImageHolder) temp)
.getImageURL(ImageSize.MEGA);
artistName = ((MusicEntry) temp).getName();
}
}
} catch (Exception e) {
Log.i("images", e.getMessage());
}
return artistImages;
}
}
Quindi, non sono sicuro di come impostarlo correttamente ed è ora di chiedere aiuto. Dopo la mia giusta quota di tentativi falliti, il lato positivo è che ho imparato molto su come rendere la mia app più efficiente. Apprezzerei qualche consiglio.
Soluzione
Di seguito è riportato il codice che dovrebbe darti un'idea equa su come si dovrebbe gestire il compito dell'adattatore e dell'async.Come @abentspoon e @fixpoint, sono anche confuso come stai usando queste variabili.Ma sto ignorando questi e concentrati idealmente come la struttura del codice dovrebbe essere per il tuo caso.
Adapter.GetView () Il metodo è chiamato una volta per ciascuna cella o oggetto nella griglia.Se si esegue l'attività Async da GetView () verrà eseguito per ogni articolo.Penso che sia per questo che stai vedendo la quantità di stampe.
public class ArtistImage {
public String image;
public String name;
}
public class LoadImages extends AsyncTask<String, Integer, List<ArtistImage>> {
private List<ArtistImage> artistImages = new ArrayList<ArtistImage>();
private ArtistAdapter artistAdapter;
public LoadImages(ArtistAdapter adapter) {
artistAdapter = adapter;
}
@Override
protected List<ArtistImage> doInBackground(String... params) {
try {
for (int i = 0; i <= 10; i++) {
Collection<Artist> artistImage = Artist.getSimilar("Bon Iver", i, key);
Iterator<Artist> itr = artistImage.iterator();
while (itr.hasNext()) {
Artist temp = itr.next();
ArtistImage ai = new ArtistImage();
ai.image = ((ImageHolder) temp).getImageURL(ImageSize.MEGA);
ai.name = ((MusicEntry) temp).getName();
artistImages.add(ai);
}
}
} catch (Exception e) {
Log.i("images", e.getMessage());
}
return artistImages;
}
@Override
protected void onPostExecute(List<ArtistImage> result) {
artistAdapter.setArtistImages(result);
}
}
public class ArtistAdapter extends ... {
private List<ArtistImage> artistImages = new ArrayList<ArtistImage>();
public void setArtistImages(List<ArtistImage> images) {
this.artistImages = images;
super.notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ArtistImage image = artistImages.get(position);
// render stuff here
}
}
.
nella tua attività, oncreate o qualche evento:
ArtistAdapter aa = new ArtistAdapter();
LoadImages loadImages = new LoadImages(aa);
loadImages.execute();
.