3

我正在从 a 下载几个图像和名称Collection并将它们应用到GridView. 我在AsyncTask正常工作时遇到了一些问题。我需要从一个 url 返回两个不同的值,一个图像和名称。目前,我可以正确下载所有内容并将信息应用于我的ImageViewand TextView,但我这样做的方法仅在我调用它时才有效Adapter

问题:

当我设置我AsyncTask下载所有内容时,它只会将序列的第一个值应用于Views我的网格中。当我记录“artistImages”时,它会大量打印出该序列的其他 url,我不知道为什么会发生这种情况,但是这些 url 中的数据实际上并没有应用于我的Adapter.

我试过的:

我已经尝试设置一个循环doInBackground()来运行我的Iterator n次。

Boolean在将序列中第一组的数据应用到我的所有Views.

我已经尝试Adapter在我的AsyncTask.

我已经尝试AsyncTask在 my 中设置我的Adapter新课程,而不是创建一个新课程。

我已经尝试将我ImageView的 inonPostExecute()和我的Adapter.

我尝试在我的AsyncTask.

AsyncTask我已经尝试为 my设置一个Views,以便我Iterator可以正常运行,并且图像和名称是异步应用的。

我已经对停止循环或AsyncTask在某个点进行了大量研究,AsyncTaks在 aGridView或 with an中进行设置,并在,和一般情况下Adapter进行了更多阅读。ThreadsHandlersAsyncTask

所有这些尝试要么导致仅使用第一组序列,要么根本不下载和应用任何内容。所以,我Iterator在我的AsyncTask.

这是我用来下载图像和名称的代码。只要我在getViewmy 方法中使用它,它就可以工作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;
    }
}

所以,我不确定如何正确设置它,是时候寻求帮助了。在经历了相当多的失败尝试之后,从好的方面来说,我学到了很多关于让我的应用程序更高效的知识。我会很感激一些建议。

4

1 回答 1

3

下面的代码可以让您清楚地了解应该如何处理适配器和异步任务。像@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();
于 2012-02-24T18:36:01.690 回答