android in practice_Managing threads in thread pools(MyMovies project)

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值