Настройка цикла в AsyncTask для получения следующей итерации последовательности - PullRequest
3 голосов
/ 22 февраля 2012

Я загружаю несколько изображений и имен из Collection и применяю их в GridView. Я столкнулся с несколькими проблемами, заставляющими мою AsyncTask работать правильно. Мне нужно вернуть два разных значения, изображение и имя, из одного URL. В настоящее время я могу правильно загрузить все и применить информацию к моим ImageView и TextView, но мой метод для этого работает, только когда я вызываю это в моем Adapter.

Проблема:

Когда я настраиваю AsyncTask для загрузки всего, он применяет только первое значение последовательности к Views в моей сетке. Когда я регистрирую «artistImages», он распечатывает другие URL последовательности огромное количество раз, я не знаю, почему это происходит, но на самом деле ни один из данных из URL не применяется в моем Adapter.

Что я пробовал:

Я пытался настроить цикл в doInBackground(), чтобы он проходил мои Iterator n раз.

Я пытался использовать Boolean, чтобы остановить мой итератор, прежде чем он применяет данные из первого набора в последовательности ко всем моим Views.

Я пытался настроить Adapter в моем AsyncTask.

Я пытался установить новый AsyncTask в моем Adapter, а не создавать новый класс.

Я пытался установить ImageView в onPostExecute() и в Adapter.

Я пытался использовать разные параметры в AsyncTask.

Я попытался настроить AsyncTask для моего Views, чтобы мой Iterator мог работать функционально, а изображения и имя применялись асинхронно.

Я провел много исследований по остановке цикла или AsyncTask в определенный момент, настройке AsyncTaks в GridView или Adapter и гораздо большему чтению по Threads , Handlers и AsyncTask в целом.

Все эти попытки либо приводят к тому, что используется только первый набор использованной последовательности, либо вообще ничего не загружаются и не применяются. Итак, мне довольно трудно использовать мой Iterator в моем AsyncTask.

Это код, который я использую для загрузки изображений и имен. Это работает до тех пор, пока я использую его в методе getView my Adapter.

Используется для загрузки изображений и имен:

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

Просто чтобы показать, что все есть:

private Iterator<Artist> itr;
private Collection<Artist> artistImage;
private String artistImages = null;
private String artistName = null;
private int i = 0;

AsyncTask: Я называю это в getView моего 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;
    }
}

Итак, я не уверен, как правильно это настроить, и пришло время обратиться за помощью. После моей большой доли неудачных попыток, с другой стороны, я многое узнал о том, как сделать мое приложение более эффективным. Буду признателен за несколько советов.

1 Ответ

3 голосов
/ 24 февраля 2012

Ниже приведен код, который должен дать вам четкое представление о том, как вы должны справиться с адаптером и асинхронной задачей.Как @ABentSpoon и @Fixpoint, я также запутался, как вы используете эти переменные.Но я игнорирую их и в идеале сосредотачиваюсь на том, какой должна быть структура кода для вашего случая.

Метод Adapter.getView () вызывается один раз для каждой ячейки или элемента в сетке.Если вы собираетесь запустить асинхронную задачу из getView (), она будет выполняться для каждого элемента.Я думаю, именно поэтому вы видите огромное количество отпечатков.

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

В вашей активности либо onCreate, либо какое-либо событие:

ArtistAdapter aa = new ArtistAdapter();
LoadImages loadImages = new LoadImages(aa);
loadImages.execute();
...