在 AsyncTask 中设置循环以检索序列的下一个迭代

发布于 2025-01-08 18:36:01 字数 3129 浏览 2 评论 0原文

我正在从 Collection 下载多个图像和名称,并将它们应用到 GridView 中。我在使 AsyncTask 正常工作时遇到了一些问题。我需要从一个 url 返回两个不同的值,即图像和名称。目前,我可以正确下载所有内容并将信息应用到我的 ImageViewTextView,但我执行此操作的方法仅在我在 中调用它时才有效适配器。

问题

当我设置 AsyncTask 来下载所有内容时,它仅将序列的第一个值应用于网格中的Views。当我记录“artistImages”时,它会多次打印出该序列的其他网址,我不知道为什么会发生这种情况,但网址中的任何数据都没有实际应用于我的适配器中代码>.

我尝试过的:

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

我尝试使用 Boolean 来停止我的迭代器,然后再将序列中第一组的数据应用到我的所有 Views

我尝试在 AsyncTask 中设置 Adapter

我尝试在我的 Adapter 中设置一个新的 AsyncTask,而不是创建一个新类。

我尝试在 onPostExecute()Adapter 中设置我的 ImageView

我尝试在 AsyncTask 中使用不同的参数。

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

我已经做了很多关于在某个点停止循环或 AsyncTask、在 GridView 中设置 AsyncTaks 或使用 AsyncTaks 的研究。 code>Adapter,以及有关 ThreadsHandlersAsyncTask 的更多阅读。

所有这些尝试要么导致仅使用序列的第一组,要么根本不下载和应用任何内容。因此,我在 AsyncTask 中使用 Iterator 时遇到了相当困难。

这是我用来下载图像和名称的代码。只要我在 AdaptergetView 方法中使用它,它就可以工作。

用于下载图像和名称:

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 我的适配器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;
    }
}

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

I'm downloading several images and names from a Collection and applying them in a GridView. I've run into a few problems getting my AsyncTask working correctly. I need to return two different values, an image and name, from one url. At the moment, I can correctly download everything and apply the info to my ImageView and TextView, but my method for doing this only works while I call it in my Adapter.

Problem:

When I set up my AsyncTask to download everything, it only applies the first value of the sequence to the Views in my grid. When I log "artistImages", it prints out the other urls of the sequence an enormous number of times, I don't know why this happens, but none of the data from the urls is actually applied in my Adapter.

What I've tried:

I've tried setting up a loop in doInBackground() to run through my Iterator n times.

I've tried using a Boolean to stop my iterator before it applies the data from the first set in the sequence to all my Views.

I've tried setting my up Adapter in my AsyncTask.

I've tried setting my a new AsyncTask in my Adapter, rather than creating a new class.

I've tried setting my ImageView in onPostExecute() and in my Adapter.

I've tried using different parameters in my AsyncTask.

I've tried setting up a AsyncTask for my Views, so that my Iterator can run functionally and the images and name are applied asynchronously.

I've done a lot of research on stopping the loop or AsyncTask at a certain point, setting up AsyncTaks in a GridView or with an Adapter, and a lot more reading on Threads, Handlers, and AsyncTask in general.

All of these attempts either result in only the first set of the sequence being used or nothing being downloaded and applied at all. So, I'm having a pretty difficult time using my Iterator in my AsyncTask.

This is the code I'm using to download the images and names. This works as long as I'm using it within the getView method my Adapter.

Used to download images and names:

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

Just to show what everything is:

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

AsyncTask: I'm calling this in getView of my 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;
    }
}

So, I'm unsure how to set this up correctly and it's time to ask for some help. After my fair share of failed attempts, on the plus side I've learned a lot about making my app more efficient. I'd appreciate some advice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情感失落者 2025-01-15 18:36:01

下面的代码应该可以让您清楚地了解如何处理适配器和异步任务。就像@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();

Below is the code that should give you fair idea on how you should deal with adapter and async task. Like @ABentSpoon and @Fixpoint, I'm also confused how you are using these variables. But I'm ignoring these and focusing on ideally how the code structure should be for your case.

Adapter.getView() method is called once for each cell or item in the grid. If your going to run async task from within getView() it will be executed for each item. I think that is why you are seeing enormouse amount of prints.

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

In your activity, either onCreate or some event:

ArtistAdapter aa = new ArtistAdapter();
LoadImages loadImages = new LoadImages(aa);
loadImages.execute();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文