3

からいくつかの画像と名前をダウンロードし、Collectionそれらを に適用していGridViewます。AsyncTask正しく動作させるためにいくつかの問題に遭遇しました。1 つの URL から、画像と名前の 2 つの異なる値を返す必要があります。現時点では、すべてを正しくダウンロードして情報を myImageViewTextViewに適用できますが、これを行う方法は my で呼び出している間のみ機能しますAdapter

問題:

AsyncTaskすべてをダウンロードするように設定すると、シーケンスの最初の値のみがViewsグリッドに適用されます。「artistImages」をログに記録すると、シーケンスの他の URL が何度も出力されます。なぜこれが起こるのかわかりませんが、URL からのデータは実際には私のAdapter.

私が試したこと:

ndoInBackground()実行するためにループを設定しようとしました。Iterator

シーケンスBooleanの最初のセットのデータをすべてのViews.

で設定してみましAdapterAsyncTask

新しいクラスを作成するのではなく、に新しいクラスをAsyncTask設定しようとしました。Adapter

私は myと in myImageViewを設定しようとしました。onPostExecute()Adapter

でさまざまなパラメーターを使用してみましたAsyncTask

私は機能的に実行でき、画像と名前が非同期に適用されるように、AsyncTask私の に を設定しようとしました。ViewsIterator

ループの停止やAsyncTask特定の時点での設定AsyncTaksGridViewまたは を使用した設定、および、、および一般Adapterに関する多くの読み取りについて、多くの調査を行いました。ThreadsHandlersAsyncTask

これらの試みはすべて、シーケンスの最初のセットのみが使用されるか、何もダウンロードされず、適用されません。だから、私は myIteratorで myを使うのにかなり苦労してい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;
    }
}

それで、これを正しく設定する方法がわからないので、助けを求める時が来ました. 試行錯誤のかなりの割合で失敗した後、プラス面として、アプリをより効率的にすることについて多くのことを学びました. アドバイスをいただければ幸いです。

4

1 に答える 1

3

以下は、アダプターと非同期タスクをどのように処理する必要があるかについての公正なアイデアを提供するコードです。@ABentSpoon や @Fixpoint と同様に、これらの変数をどのように使用しているかについても混乱しています。しかし、私はこれらを無視し、理想的にはコード構造があなたのケースにどのようであるべきかに焦点を当てています.

Adapter.getView() メソッドは、グリッド内のセルまたはアイテムごとに 1 回呼び出されます。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 に答える