如何使用 AsyncTask 将图像从 drawable 加载到 listView
Posted
技术标签:
【中文标题】如何使用 AsyncTask 将图像从 drawable 加载到 listView【英文标题】:How to use AsyncTask to load images from drawable into listView 【发布时间】:2013-09-11 16:03:04 【问题描述】:我有一个简单的 ListView,左边有图片,右边有文字。目前我正在使用 LazyAdapter 根据菜肴名称从可绘制资源中加载图像。
我已经创建了一组图像 ID,并将使用它来设置图像视图。
问题是,滚动不流畅,我知道这是因为所有图像加载都是由主线程完成的。我在 Google 上搜索了很多关于 AsyncTask 的信息,它允许我们运行后台线程。我不知道如何使用 AsyncTask 来按任务实现,因为我在 AsyncTask 上看到的所有示例都有从 URL 下载的图像。
请帮助我使用 AsyncTask 将图像列表从可绘制对象加载到位图。
这是我的邮件类:
ARRAY.image 是一个整数数组,其中包含图像 ID,在适配器中用于设置 ImageView
package love.cookbook.FirstPage;
import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.MenuItem;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.*;
import android.view.*;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.*;
public class ListViewSampleActivity extends SherlockListActivity
LazyAdapter adapter;
public String packageName;
public int imageID;
String ingredientsImageName;
public mysqliteHelper dbHelper;
Cursor cur;
String eachIngredientsImageName [];
String listItemName;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
Intent intent = getIntent();
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
dbHelper = new MySqliteHelper(this);
ListView list=(ListView)findViewById(android.R.id.list);
final FirstPageActivity firstPage = new FirstPageActivity();
ARRAY.dishes = intent.getStringArrayExtra("DISHES");
ARRAY.description = intent.getStringArrayExtra("DESCRIPTION");
ARRAY.timeToPrepare = intent.getStringArrayExtra("TIMETOPREPARE");
ARRAY.lock = intent.getStringArrayExtra("LOCKVALUE");
ARRAY.imageName = intent.getStringArrayExtra("IMAGENAME");
ARRAY.nonVeg = intent.getStringArrayExtra("NONVEG");
ARRAY.isFavourite = intent.getStringArrayExtra("ISFAVOURITE");
/*
* This code snippet is used to fetch the image id from the resource folder from the name fetched from database.
*/
ARRAY.image = new int[ARRAY.imageName.length];
packageName=this.getPackageName();
for(int i=0;i<ARRAY.imageName.length;i++)
ARRAY.image[i]=getResources().getIdentifier(ARRAY.imageName[i].toLowerCase(), "drawable", packageName);
adapter=new LazyAdapter (this, ARRAY.dishes,ARRAY.description,ARRAY.timeToPrepare,ARRAY.image,ARRAY.lock,ARRAY.nonVeg);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener()
public void onItemClick(AdapterView<?> parent, View view, int position,
long id)
);
这是我的适配器类:
package love.cookbook.FirstPage;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class LazyAdapter extends BaseAdapter
private Activity activity;
private String[] dishes;
private String[] recipeDescripion;
private String[] timeToPrepare;
private String[] lock;
private String[] nonVeg;
private int [] images;
ViewHolder holder;
Bitmap bitmap;
private static LayoutInflater inflater=null;
public LazyAdapter(Activity a, String[] dishes, String[] recipeDescription,String[] timeToPrepare,int[] images,String [] lock,String [] nonVeg)
activity = a;
this.dishes=dishes;
this.images=images;
this.bitmap = bitmap;
this.recipeDescripion=recipeDescription;
this.timeToPrepare=timeToPrepare;
this.lock=lock;
this.nonVeg=nonVeg;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public View getView(int position, View convertView, ViewGroup parent)
//View vi=convertView;
if(convertView==null)
//vi = inflater.inflate(R.layout.item, null);
convertView = inflater.inflate(R.layout.item,parent, false);
//image = (ImageView)vi.findViewById(R.id.imageView);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.imageView2);
holder.vegNonveggImageView = (ImageView) convertView.findViewById(R.id.imageView3);
holder.textView1 = (TextView)convertView.findViewById(R.id.textView1);
holder.textView2 = (TextView)convertView.findViewById(R.id.textView2);
holder.textView3 = (TextView)convertView.findViewById(R.id.textView3);
convertView.setTag(holder);
else
holder = (ViewHolder)convertView.getTag();
holder.textView1.setText(dishes[position]);
holder.image.setImageResource(images[position]);
holder.textView2.setText(recipeDescripion[position]);
holder.textView3.setText(timeToPrepare[position]);
if(nonVeg[position].equals("1"))
holder.vegNonveggImageView.setImageResource(R.drawable.non_veg_symbol);
else
holder.vegNonveggImageView.setImageResource(R.drawable.veg_symbol);
return convertView;
public int getCount()
return dishes.length;
public Object getItem(int position)
return position;
public long getItemId(int position)
return position;
public class ViewHolder
ImageView image;
TextView textView1;
TextView textView2;
TextView textView3;
ImageView vegNonveggImageView;
【问题讨论】:
您可以使用Universal Image Loader进行异步图片显示。 【参考方案1】:您的滚动不流畅问题可能是由于图像占用过多内存造成的。
您可以在 Eclipse 中通过 DDMS 透视图查看分配的内存大小来检查它是否看起来太大。
这可以通过以下方式检查:
打开 DDMS 透视图:窗口 > 打开透视图 > DDMS, 找到设备视图:窗口 > 显示视图 > 设备 在列表中选择您的应用(模拟器必须正在运行) 点击更新堆(看起来像一个半满的绿色容器) 找到堆视图:窗口 > 显示视图 > 堆 单击原因 GC如果1-byte array(byte[], boolean[])
类型的总大小太大,这可能会导致滚动问题。
我认为AsyncTask
不会解决您的问题,因为无论如何更新视图都必须在 UI(主)线程上完成。
如果您加载的图像太大,您可以使用以下方法最小化它们:
Bitmap smallIcon = Bitmap.createScaledBitmap(bigIcon, width, height, false);
希望对你有帮助
【讨论】:
您好,感谢您的信息。我的 1 字节数组的总大小为 14.56MB,计数为 532。您能否详细说明这些统计数据的含义?在将所有图像发送到 LazyAdapter 之前,我是否需要创建一个位图数组来减小所有图像的大小? @user2757578 是的,这似乎很多! 532 并不意味着太多,但 14.56MB 意味着您很可能在大型位图中分配了很多内存(它们以字节 [] 的形式保存到内存中)。 Android 应用程序通常允许分配大约 16MB,因此几乎所有内存都被图像占用。您是否尝试使用上面的 createScaledBitmap 方法减小它们的大小?另外,您使用的图像有多大(像素)?如果它们在您的资源文件夹中,您可以尝试手动减小它们的大小。以上是关于如何使用 AsyncTask 将图像从 drawable 加载到 listView的主要内容,如果未能解决你的问题,请参考以下文章
如果使用 Asynctask 将 URL 存储在 ArrayList 中,如何从服务器下载图像?
如何从服务器下载图像如果使用Asynctask存储在ArrayList中的URL?
Android:使用 Asynctask 从 Web 加载图像