【发布时间】:2012-02-24 21:28:00
【问题描述】:
我的应用程序允许用户使用他们设备的相机应用程序拍照,这些照片保存到应用程序特定的文件夹中。
然后,用户可以选择使用他们选择的设备电子邮件应用程序将他们选择的任何图像发送给他们的联系人之一。
遗憾的是,“选择要发送的图像”对话框最初需要很长时间才能加载,并且在滚动时非常“不稳定”(经常出现明显的停顿)。我怀疑这是因为图像非常大——用我的相机拍摄的照片每张大约 2.3MB。因此,初始屏幕(显示 15 张图像)需要从磁盘上拉出大约 34.5MB 才能渲染。
GridView 布局.xml
<!-- ... -->
<GridView
android:id="@+id/gvSelectImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:numColumns="3"
android:gravity="center" />
<!-- ... -->
适配器 getView()
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
File pic = pics[position];
View checkedImageView =
LayoutInflater.from(context).inflate(R.layout.checked_image,
parent, false);
final ImageView imageView =
(ImageView) checkedImageView.findViewById(R.id.checkableImage);
/* LOAD IMAGE TO DISPLAY */
//imageView.setImageURI(pic.toURI())); // "exceeds VM budget"
Bitmap image;
try {
int imageWidth = 100;
image = getBitmapFromFile(pic, imageWidth); // TODO: slooow...
} catch (IOException e) {
throw new RuntimeException(e);
}
imageView.setImageBitmap(image);
/* SET CHECKBOX STATE */
final CheckBox checkBoxView =
(CheckBox) checkedImageView.findViewById(R.id.checkBox);
checkBoxView.setChecked(isChecked[position]);
/* ATTACH HANDLERS */
checkBoxView.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
CheckableLocalImageAdapter.this.isChecked[position] =
checkBoxView.isChecked();
}
});
imageView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
checkBoxView.setChecked(!checkBoxView.isChecked());
}
});
return checkedImageView;
}
getBitmapFromFile() 刚刚改编自https://stackoverflow.com/a/823966/633626 给出的答案。我注意到那里的代码调用了两次decodeStream(),可能会使我的 I/O 翻倍,但我认为即使我将渲染时间减半,对话框仍然会太慢而且太生涩。
如果相关的话,我的测试手机是标准的三星 Galaxy S II。我怀疑旧设备会更慢/更不稳定。
在这里提高性能的最佳方法是什么?我猜测 AsyncTask 的组合来加载每个图像(这样对话框可以在所有图像被渲染之前加载)和某种缓存(这样滚动不需要重新渲染图像并且不是生涩),但我我不知道如何将这些碎片与我的拼图的其余部分结合起来。
【问题讨论】:
标签: android performance