Android 列表视图中的性能较慢
我的Android应用程序出现了一个非常奇怪的问题。简单地说,当我将图像内容放入Android 列表视图中的性能较慢,android,image,listview,android-asynctask,adapter,Android,Image,Listview,Android Asynctask,Adapter,我的Android应用程序出现了一个非常奇怪的问题。简单地说,当我将图像内容放入列表视图项中时,就会出现问题。 例如;假设我有一个片段,布局如下 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width=
列表视图项中时,就会出现问题。
例如;假设我有一个片段
,布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@android:id/list" />
</LinearLayout>
你们知道为什么会这样吗?我找不到任何理由,也找不到解决这一问题的办法。
提前谢谢
tl;dr:当我将图像放入ImageView
时,我的列表视图的速度非常慢。它们从何而来(ram、磁盘、互联网)似乎并不重要。每当我执行imageView.setImageBitmap()
或imageView.setDrawable()
时,性能会急剧下降,几乎不可能进行滚动。因为您是从主(UI)线程中的资源加载图像,这就是它看起来不稳定的原因。所以像这样在asynktask中加载图像
public class ListAdapter extends ItemViewHolder<ClipData.Item> {
@ViewId(R.id.listimage)
ImageView image;
@ViewId(R.id.listtitle)
TextView title;
@ViewId(R.id.listsubtitle)
TextView subtitle;
public BeetListAdapter(View view) {
super(view);
}
@Override
public void onSetValues(BeetItem item, PositionInfo positionInfo) {
title.setText(item.getTitle());
subtitle.setText(item.getLatinname());
getBitmapFromAsset(item.getFirstImageName(), image);
getView().setTag(R.id.itemid, item.getId());
}
private void getBitmapFromAsset(final String strName,final ImageView imageView)
{
new AsyncTask<Void,Void,Bitmap>(){
@Override
protected Bitmap doInBackground(Void... voids) {
try{
AssetManager assetManager = getContext().getAssets();
InputStream istr = null;
try {
istr = assetManager.open("images/" + strName + ".jpg");
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(istr);
return bitmap;
}catch (Throwable e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if(result!=null){
image.setImageBitmap(result);
}
}
}.execute();
}
}
公共类ListAdapter扩展了ItemViewHolder{
@ViewId(R.id.listimage)
图像视图图像;
@视图id(R.id.listtitle)
文本视图标题;
@ViewId(R.id.listsubtitle)
文本视图字幕;
公用列表适配器(视图){
超级(视图);
}
@凌驾
设置值上的公共无效(BeetItem项、PositionInfo PositionInfo){
title.setText(item.getTitle());
subtitle.setText(item.getLatinname());
getBitmapFromAsset(item.getFirstImageName(),image);
getView().setTag(R.id.itemid,item.getId());
}
私有void getBitmapFromAsset(最终字符串strName,最终图像视图)
{
新建异步任务(){
@凌驾
受保护位图doInBackground(无效…无效){
试一试{
AssetManager AssetManager=getContext().getAssets();
InputStream istr=null;
试一试{
istr=assetManager.open(“images/”+strName+“.jpg”);
}捕获(IOE异常){
e、 printStackTrace();
}
位图位图=位图工厂.decodeStream(istr);
返回位图;
}捕获(可丢弃的e){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(位图结果){
super.onPostExecute(结果);
如果(结果!=null){
image.setImageBitmap(结果);
}
}
}.execute();
}
}
缓存图像如果可能,将其缩小。我可以帮你完成所有这些任务 平心而论,以上这些都没有真正解决我的问题,我决定实施
作为参考,这是我初始化Android Universal Image Loader时使用的配置
没有实现AsyncTask
,我现在在应用程序中有了非常好的用户体验。不要硬编码LruMemoryCache
。因为在某些设备上,您将收到:
Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1)
以下是快速加载图像和滚动列表视图的选项:
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
int memClass;
memClass = ( (ActivityManager)this.getSystemService( Context.ACTIVITY_SERVICE ) )
.getMemoryClass();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.threadPoolSize(1)//from 1-5
.denyCacheImageMultipleSizesInMemory()
.threadPriority(Thread.MAX_PRIORITY)
.tasksProcessingOrder(QueueProcessingType.LIFO)
// .tasksProcessingOrder(QueueProcessingType.FIFO) /or this
.memoryCache(new LruMemoryCache(memClass * 1024 * 1024/8))
.diskCacheExtraOptions(480, 320, null)
.build();
ImageLoader.getInstance() .init(config);
您是否尝试按需要的大小缩放图像?另外,我建议您将图像加载到另一个线程(可能是异步任务)并缓存图像。您正在使用的图像的大小和尺寸是多少?似乎这并不完全是我想要的。图像加载速度非常快,性能也要好得多。但是,适配器会在第一个列表项上随机设置图像,当它随机放置图像后,它会转到下一个列表项,直到所有图像视图都正确设置为止。这不是我预期的行为。谢谢你的建议。你提供的图书馆不是我要找的。是
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.threadPoolSize(5)
.threadPriority(Thread.MAX_PRIORITY)
.tasksProcessingOrder(QueueProcessingType.FIFO)
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
.diskCacheExtraOptions(480, 320, null)
.build();
ImageLoader.getInstance().init(config);
Fatal signal 11 (SIGSEGV) at 0x00000010 (code=1)
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
int memClass;
memClass = ( (ActivityManager)this.getSystemService( Context.ACTIVITY_SERVICE ) )
.getMemoryClass();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.threadPoolSize(1)//from 1-5
.denyCacheImageMultipleSizesInMemory()
.threadPriority(Thread.MAX_PRIORITY)
.tasksProcessingOrder(QueueProcessingType.LIFO)
// .tasksProcessingOrder(QueueProcessingType.FIFO) /or this
.memoryCache(new LruMemoryCache(memClass * 1024 * 1024/8))
.diskCacheExtraOptions(480, 320, null)
.build();
ImageLoader.getInstance() .init(config);