![](https://img-my.csdn.net/uploads/201212/31/1356938765_1144.jpg)
every list item is created in the list adapter’s getView method, and this method is called whenever you scroll the list to see more items. We could use this method to spawn a thread that downloads the image thumbnail because if we were to do it in place then getView would block.
![](https://img-my.csdn.net/uploads/201212/31/1356938871_5988.jpg)
A commonly used kind of thread pool is one that manages a fixed number of threads that execute tasks posted to a shared queue.
First, the movie_item.xml layout because we need an ImageView next to the movie title text view. Second, we need to change the adapter code to trigger the image download whenever getView is called.
movie_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical">
<ImageView android:id="@+id/movie_icon"
android:layout_width="50dip"
android:layout_height="50dip"
android:scaleType="centerCrop"/>
<CheckedTextView
android:id="@android:id/text1"
android:layout_width="0px"
android:layout_height="fill_parent"
android:layout_weight="0.9"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:checkMark="?android:attr/listChoiceIndicatorMultiple" />
</LinearLayout>
MovieAdapter.class
/**
* Another perfectly valid approach would be to create a Movie model class.
* get rid of the HashMap.
*/
//The MovieAdapter keeps track of selected movies
//Adapter separating data from its representation on the screen
public class MovieAdapter extends ArrayAdapter<String> {
private HashMap<Integer,Boolean> movieCollection
=new HashMap<Integer,Boolean>();//storing movie state data which is transient
private String[] movieIconUrls;//List of movie image URLs
private ThreadPoolExecutor executor;//Controls thread pool
public MovieAdapter(Context context) {
super(context,R.layout.movie_item,android.R.id.text1,context.getResources().getStringArray(R.array.movies));
// TODO Auto-generated constructor stub
//Read image URLs into array
movieIconUrls=context.getResources().getStringArray(R.array.movie_thumbs);
//Create new thread pool
executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(5);
}
public void toggleMovie(int position){
if(!isInCollection(position)){
movieCollection.put(position, true);
}
else{
movieCollection.put(position, false);
}
}
public boolean isInCollection(int position){
return movieCollection.get(position) == Boolean.TRUE;
}
@Override
//returns the view needed for each item.
//cache and reuse item views via convertView for performance reasons
public View getView(int position,View convertView,ViewGroup parent){
View listItem=super.getView(position, convertView, parent);
CheckedTextView checkMark=(CheckedTextView)listItem.findViewById(android.R.id.text1);
checkMark.setChecked(isInCollection(position));
ImageView imageView =(ImageView)listItem.findViewById(R.id.movie_icon);
imageView.setImageDrawable(null);
imageView.setTag(position);//link position to image view
downloadImageForView(position,imageView);
return listItem;
}
private void downloadImageForView(int position, ImageView imageView){
final Handler handler=new ImageHandler(position,imageView);
final String imageUrl=movieIconUrls[position];
//Schedule new download task
executor.execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
try{
URL url=new URL(imageUrl);
Bitmap image=BitmapFactory.decodeStream(url.openStream());
Bundle data=new Bundle();
data.putParcelable("iamge", image);
Message message=new Message();
message.setData(data);
handler.sendMessage(message);
}catch(Exception e){
e.printStackTrace();
}
}
});
}
}
create array file movie_thumbs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="movie_thumbs">
<item>http://ia.media-imdb.com/images/M/MV5BMTg4MDA2MDM5Nl5BMl5BanBnXkFtZTcwOTU5MTQ2Mg@@._V1._CR328,0,1392,1392_SS90_.jpg
</item>
<item>http://ia.media-imdb.com/images/M/MV5BMTI5MzEwMDYxMV5BMl5BanBnXkFtZTYwNzg5NzM2._V1._CR0,0,320,320_SS90_.jpg
</item>
......
<item>http://ia.media-imdb.com/images/M/MV5BMTk4MDk2NDI5Nl5BMl5BanBnXkFtZTcwMDM3MjcwMg@@._V1._CR120,0,481,481_SS90_.jpg
</item>
</string-array>
</resources>
ImageHandler.java defines the code to update the ImageViews:
public class ImageHandler extends Handler {
private int position;
private ImageView imageView;
public ImageHandler(int position, ImageView imageView) {
this.position = position;
this.imageView = imageView;
}
@Override
public void handleMessage(Message msg){
int forPosition=(Integer)imageView.getTag();
if(forPosition!=this.position){
return;
}
Bitmap image=msg.getData().getParcelable("image");
imageView.setImageBitmap(image);
}
}