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.

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top