android in practice_Implementing jobs with AsyncTask(MyMovies project)

android in practice_Implementing jobs with AsyncTask(MyMovies project)_第1张图片

AsyncTask offers an easy-to-use (but more limited).

You need to perform an asynchronous job that follows a pre-process/process/postprocess pattern, and are looking for a code template that allows you to report progress
to the user or otherwise update the UI in each step.

In the last technique, we retrieved movie thumbnail images by having a simple downloader helper method fork a new thread that downloaded the image, and then passed it to a custom handler object that updated the image on the list view.

create the AsyncTask class DownloadTask:

public class DownloadTask extends AsyncTask<String,Void,Bitmap> {
	   private int position;
	   private ImageView imageView;
	   private Drawable placeholder;
	   
	   public DownloadTask(int position,ImageView imageView){
		   this.position=position;
		   this.imageView=imageView;
		   Resources resources=imageView.getContext().getResources();
		   this.placeholder=resources.getDrawable(android.R.drawable.gallery_thumb);
	   }

	   //Called before task runs
	   protected void onPreExecute(){
		   imageView.setImageDrawable(placeholder);
	   }
	   //task logic
		protected Bitmap doInBackground(String... inputUrls) {
			try{
				URL url=new URL(inputUrls[0]);
				return BitmapFactory.decodeStream(url.openStream());
			}catch(Exception e){
				e.printStackTrace();
				return null;
			}
		}
	  //called after task runs
		protected void onPostExecute(Bitmap result){
			int forPosition=(Integer)imageView.getTag();
			if(forPosition==this.position){
				this.imageView.setImageBitmap(result);
			}
		}
}
worker arguments (String), worker progress (Void), and worker result (Bitmap).

trigger the task,modify the class MovieAdapter:

/**
 * 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>  {
	//storing movie state data
	//this state is transient
	private HashMap<Integer,Boolean> movieCollection=new HashMap<Integer,Boolean>();
	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);   
	}
	

	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  
	        String imageUrl=movieIconUrls[position];
	        new DownloadTask(position,imageView).execute(imageUrl);
	        return listItem;  
	}
}
first, the absence of any explicit interthread communication using handlers and messages, and second, a higher code quality achieved by having all code related to the download task in a single class.


你可能感兴趣的:(android in practice_Implementing jobs with AsyncTask(MyMovies project))