android in practice_Managing threads in thread pools(MyMovies project)

 
 android in practice_Managing threads in thread pools(MyMovies project)_第1张图片 
 

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.

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


你可能感兴趣的:(android in practice_Managing threads in thread pools(MyMovies project))