我从数据库中提取数据,各种字符串和表示外部目录中图像的图像路径的字符串。
我的问题是当列表视图加载来自光标对象的所有图像被加载到第一个列表视图时,这是耗时的,然后每个图像被正确加载到后续视图中。
所以我的问题是为什么数据库中的每个图像都被加载到第一个列表视图中,而不是根据需要加载到每个列表视图中的一个图像。
这是我的Cursor适配器代码,我使用异步任务从数据库加载图像(事先道歉它的分配代码!)。
任何意见都赞赏。
@Override
public void bindView(View v, Context context, final Cursor c) {
/*
* Binds the data from each row (stored in cursor object) to the ListView.xml
* first free up List object if not in view of the screen by holding a ref to it, therefore dont
* waste memeory and tiome recreating each view when out of viewable list to user
*/
ViewHolder holder = (ViewHolder) v.getTag();
String diveSite = c.getString(c.getColumnIndexOrThrow(diveDataBase.KEY_DIVESITE));
holder.title_text.setText(diveSite);
String date = c.getString(c.getColumnIndexOrThrow(diveDataBase.KEY__DIVEDATE));
holder.date_text.setText(date);
String rating = c.getString(c.getColumnIndexOrThrow(diveDataBase.KEY_DIVERATING));
holder.bar.setNumStars(5);
holder.bar.setRating( Float.parseFloat(rating));
String diveNumber= c.getString(c.getColumnIndexOrThrow(diveDataBase.KEY__DIVENUMBER));
String diveImagePath = c.getString(c.getColumnIndex(diveDataBase.KEY_DIVEPICTURE));
c.moveToLast();
noOfRows = Integer.parseInt(c.getString(c.getColumnIndex(diveDataBase.KEY__DIVENUMBER)));
holder.dive_no.setText(diveNumber+"/"+noOfRows);
//set image here once taken form external string path, and resized bitmap conversion
getImageAsynch = (getBitmapImage) new getBitmapImage(v).execute(diveImagePath);
这是asynch内部类,其中图像从路径获取到ext目录,调整大小,然后填充视图持有者......
class getBitmapImage扩展了AsyncTask {
private View view;
private ViewHolder holderB;
public getBitmapImage(View v) {
// TODO Auto-generated constructor stub, takes ViewGroup as arg
//ViewGroup parent;
view=v;
holderB=new ViewHolder();
}
@Override
protected Bitmap doInBackground(String... imagePath) {
/*
* get image path and decode to bitmap
* First must make sure image loaded from DB base 64 is not loaed into memory
* at full size ie 1028 * 800 pixels
* Instead we use BitMapOptions object methods inJustDecodeBounds
* to stop autoloading of image,
* then we scale down the image for loading into memory using
* BitMapOPtiontions.inSampleSize method
* This will significantly reduce memory usage and time req to load images into list view
*
* first check if user wants to preview images (boolean displayImagesUserChoice), if not return null,
* this value is passed from dialog propmt in ViewListOfDives
* and passed to ItemAdpter constructor
*/
if(displayImagesUserChoice){
if(!isCancelled()){
String diveImagePath = imagePath[0];
File imagePathFile = new File(diveImagePath);
try {
final int IMAGE_MAX_SIZE = 3000;
FileInputStream streamIn = new FileInputStream(imagePathFile);
// Decode image size and setInJBounds = true to avoid auto memory allocation for large image
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(streamIn, null, o);
streamIn.close();
-----allot of resizing image code here have removed for an easier read---
streamIn.close();
b.recycle();
System.gc();
} else {
bitmap = BitmapFactory.decodeStream(streamIn);
resizedImage = reSizeImage(bitmap);
streamIn.close();
noOfImagesloaded++;
System.gc();
}
//resizedImage = reSizeImage(bitmap);
}catch(IOException exe){
exe.printStackTrace();
}catch(OutOfMemoryError exc){
exc.printStackTrace();
//Toast.makeText(this, "Something went wrong! Try again...", Toast.LENGTH_SHORT).show();
}catch(NullPointerException nullpoint){
nullpoint.printStackTrace();
//end try catch
}
}//end if anstch class notCancelled from the onCakPressed method of viewListOfDives
else if(isCancelled()){
Log.d("ItemAdpter Aycnh", "Do in background cancelled");
}
Log.d("ItemApdter Aycnh", "No of Images loaded = "+ noOfImagesloaded);
//return bitmap;
}//end if displayImagesUserChoice=true, if not true resizedIMage is returned as null to onPostExecute
return resizedImage;
}//end do in background
@Override
protected void onPostExecute(Bitmap bitmap) {
//intilise holder to listview.xml ImageView
holderB.displayImage = (ImageView) view.findViewById(R.id.iv_list_image); //image view
//ImageView displayImage = (ImageView) view.findViewById(R.id.iv_list_image);
if(bitmap!=null ){
//set image using holder static object
holderB.displayImage.setBackground(null);
holderB.displayImage.setImageBitmap(resizedImage);
}else{
//set default image using static holder object
holderB.displayImage.setBackgroundResource(R.drawable.camera4);
}
}//end onPOstExecute
}//end getBitmap asynch
答案 0 :(得分:0)
包含文本视图和评级栏的视图持有者返回的速度比从SD卡异步获取的图像更快,因此使用图像填充视图会有延迟。异步删除图像的加载可以解决问题,但是在所有图像都加载之前GUI没有响应,所以除了使用异步任务之外别无选择。