活动在几个 ImageView 上运行缓慢。
活动在几个 ImageView 上运行缓慢。
我有一个活动,总共包含4张图片。它们都与1080x1920的设备分辨率相匹配。当我在我的Genymotion模拟器上以XML直接加载这些图片运行活动时,它运行得非常慢,并且在真实的Android设备上出现卡顿。
以下是设置:
第一张图片位于CollapsingToolbarLayout中。图像的分辨率为1080x649的PNG格式。
content_activity如下:
此图像填充父容器的宽度。它的分辨率是1080x772的PNG格式。
另外两张图片位于LinearLayout中,它们的分辨率为500x399。
总结一下,我有一个活动,其中包含4个ImageView,用适当尺寸的图片填充,对于现代Android设备来说不应该有问题。问题是由于内存消耗过高,这个活动运行得非常慢且卡顿。
我做错了什么吗?我如何进一步优化这些图片?
我查看了其他线程-内存不足问题,但似乎没有提出解决这个问题的解决方案。
问题出现的原因是图像的分辨率过高,解决方法是减小图像的分辨率和大小。
如果传递了位图的宽度和高度,可以使用以下函数:
public Bitmap getResizedBitmap(Bitmap image, int bitmapWidth, int bitmapHeight) { return Bitmap.createScaledBitmap(image, bitmapWidth, bitmapHeight, true); }
如果想保持位图的比例并减小位图的大小,则传递最大尺寸的位图,可以使用以下函数:
public Bitmap getResizedBitmap(Bitmap image, int maxSize) { int width = image.getWidth(); int height = image.getHeight(); float bitmapRatio = (float)width / (float) height; if (bitmapRatio > 0) { width = maxSize; height = (int) (width / bitmapRatio); } else { height = maxSize; width = (int) (height * bitmapRatio); } return Bitmap.createScaledBitmap(image, width, height, true); }
如果使用可绘制资源,则可以使用以下方法:
public Drawable resizeImage(int imageResource) { Display display = getWindowManager().getDefaultDisplay(); double deviceWidth = display.getWidth(); BitmapDrawable bd = (BitmapDrawable) this.getResources().getDrawable(imageResource); double imageHeight = bd.getBitmap().getHeight(); double imageWidth = bd.getBitmap().getWidth(); double ratio = deviceWidth / imageWidth; int newImageHeight = (int) (imageHeight * ratio); Bitmap bMap = BitmapFactory.decodeResource(getResources(), imageResource); Drawable drawable = new BitmapDrawable(this.getResources(), getResizedBitmap(bMap, newImageHeight, (int) deviceWidth)); return drawable; }
还提供了一个用于调整位图大小的函数:
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) { int width = bm.getWidth(); int height = bm.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); return resizedBitmap; }
通过使用以上方法,问题得到了解决,活动现在运行得非常流畅。非常感谢提供的`resizeImage()`函数!
问题的原因是Activity在使用多个ImageView时运行缓慢。解决方法如下:
1. 减小图像的大小。
2. 如果可以的话,缓存图像。
3. 在不同的线程上下载图像。使用HashMap存储图像可以使操作更简单。
当获取到图像URL列表后,遍历它们,并根据以下代码更新ImageView:
pictures.put(id,view); try{ FileInputStream in = openFileInput(id); Bitmap bitmap = null; bitmap = BitmapFactory.decodeStream(in, null, null); view.setImageBitmap(bitmap); }catch(Exception e){ new Thread(new PictureGetter(this,mHandler,id)).start(); }
更新ImageView的代码如下:
if(id!=null){ ImageView iv = pictures.get(id); if(iv!=null){ try{ FileInputStream in = openFileInput(id); Bitmap bitmap = null; bitmap = BitmapFactory.decodeStream(in, null, null); iv.setImageBitmap(bitmap); }catch(Exception e){ } }
我的图像大小都很小,最大的大小只有351KB,这就是问题的原因。为了使程序运行更流畅,图像的大小应该更小。