À l'aide de AsyncTask de charger des images dans un adaptateur personnalisé
Bien qu'il existe de nombreux tutoriels, j'en ai trouvé ça vraiment difficile à mettre en œuvre une AsyncTask pour charger des images à partir d'URI (obtenu à partir d'un fournisseur de contenu) dans un adaptateur personnalisé.
- Je obtenir le sens de base, qui est d'avoir une classe contenant une AsyncTask, ne le bitmap de la création dans le 'doInBackground", puis l'ensemble de l'ImageView dans le onPostExecute.
Le problème pour moi, étant nouveau pour android & la programmation, c'est que je ne sais pas comment faire pour passer dans mes Uri de l'AsyncTask pour chaque élément, comment créer l'image, et comment revenir à la carte.
J'ai seulement obtenu jusqu'ici avec la classe AsyncTask (ImageLoader):
package another.music.player;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.ImageView;
public class ImageLoader extends AsyncTask<String, String, Bitmap> {
private ImageView imageView;
private Bitmap bitmap = null;
@Override
protected Bitmap doInBackground(String... uri) {
//Create bitmap from passed in Uri here
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null && imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
Et ma coutume adaptateur ressemble à ceci:
package another.music.player;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.AudioColumns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
class AlbumAdapter extends CursorAdapter {
public AlbumAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
private static Uri currentSongUri;
@Override
public void bindView(View view, Context context, Cursor cursor) {
ImageView albumArt = (ImageView) view.getTag(R.id.albumArt);
TextView text1 = (TextView) view.getTag(R.id.artistTitle);
TextView text2 = (TextView) view.getTag(R.id.albumTitle);
TextView text3 = (TextView) view.getTag(R.id.totalSongs);
albumArt.setImageBitmap(null);
text1.setText(cursor.getString(cursor
.getColumnIndex(AudioColumns.ARTIST)));
text2.setText(cursor.getString(cursor
.getColumnIndex(AudioColumns.ALBUM)));
text3.setText(cursor.getString(cursor
.getColumnIndex(AlbumColumns.NUMBER_OF_SONGS)));
String currentAlbumId = cursor.getString(cursor
.getColumnIndex(BaseColumns._ID));
Integer currentAlbumIdLong = Integer.parseInt(currentAlbumId);
Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
currentSongUri = ContentUris.withAppendedId(artworkUri,
currentAlbumIdLong);
//Run ImageLoader AsyncTask here, and somehow retrieve the ImageView & set it.
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.albumitem, null);
view.setTag(R.id.albumArt, view.findViewById(R.id.albumArt));
view.setTag(R.id.artistTitle, view.findViewById(R.id.artistTitle));
view.setTag(R.id.albumTitle, view.findViewById(R.id.albumTitle));
view.setTag(R.id.totalSongs, view.findViewById(R.id.totalSongs));
return view;
}
}
Je vous serais très reconnaissant si quelqu'un pouvait me montrer comment procéder à cet égard.
Grâce.
Salut, oui je l'ai fait. Je suis plus que familier avec AsyncTasks maintenant!
Vous devriez être en utilisant AsyncTask à l'extérieur de la Carte, puis de remplir à nouveau les résultats une fois qu'il a terminé.
OriginalL'auteur Tim Malseed | 2012-08-02
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin pour passer votre
AsyncTask
la vue, de sorte qu'il peut mettre à jour lorsqu'elle est terminée:Et modifier
AsyncTask
de sorte qu'il peut gérer mixte types de paramètres:Je n'ai pas testé ce code, mais il devrait vous donner une idée.
ensuite, vous pouvez également passer contexte comme argument:
new ImageLoader().execute(view, uri, context);
et aussiContext context = (Context)parameters[2];
Donc, vous suggérez qu'un nouveau fil de discussion devrait être mis en file d'attente chaque fois que le CursorAdapter exécute bindView()? Cela va lancer un thread pour chaque ligne du curseur qui permettra de vider la batterie de l'appareil et potentiellement détruire le système de services si le max de la taille du pool est atteint
OriginalL'auteur Caner
Pourquoi faites-vous setImage dans AsyncTask? Vous pouvez le faire dans un fil. Je ne pense pas que dans cette condition AsyncTask serait bon. Mieux vous le faire dans l'autre thread.
AsyncTask
s'exécute sur l'autre thread: developer.android.com/reference/android/os/AsyncTask.htmlJe n'ai pas forcément besoin de le faire, comme je l'ai montré. L'image bitmap pourrait juste être retourné à l'adaptateur, puis l'imageview serait fixé. Je suis ouvert aux suggestions. De toutes les choses que j'ai lu, si, je crois que je devrais être à l'aide de AsyncTask, d'une certaine manière.
Je sais AsyncTask s'exécute dans un thread différent. J'ai préférée ne pas faire tâche dans AsyncTask. De toute façon si son de satisfaire à l'exigence, vous pouvez le faire dans cette.
Je ne sais pas pourquoi cette réponse a été voté en bas, @Debarati est de souligner que l'utilisation de AsyncTask dans ce contexte, c'est un plus de les tuer. Vous n'avez pas besoin de thread en commun ou d'annulation alors pourquoi ne pas simplement utiliser le Thread?
De ce que j'ai lu,
AsyncTask
vous permet de communiquer facilement avec l'INTERFACE utilisateur,Thread
ne le fait pas.OriginalL'auteur Debarati