我从服务器加载大约20张大小为50-70K的图片,然后在ListView
中显示。最初我将数据存储为Bitmap
,导致内存快速耗尽。然后我决定压缩所有这些位图文件并存储在内容提供程序Media
中。因此,在我的适配器中,用户数据仅包含图像文件的Uri
。
然而它根本没有解决问题,它运行时间稍长,但在加载约10张图片后仍然崩溃。这是编译器的错误日志
1048576-byte external allocation too large for this process
VM won't let us allocate 1048576 bytes
我将每个bitmap
数据设置为ImageView
之后,我甚至会清理它,并删除存储在sdcard
@Override
public void onDestroy() {
// clean up
for (User user : userList) {
getContentResolver().delete(user.getImageUri(), null, null);
}
super.onDestroy();
}
private Uri constructUriFromBitmap(Bitmap bitmap) {
ContentValues values = new ContentValues(1);
values.put(Media.MIME_TYPE, "image/jpeg");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
try {
OutputStream outStream = getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
outStream.close();
}
catch (Exception e) {
Log.e(TAG, "exception while writing image", e);
}
bitmap.recycle();
return uri;
}
现在我已经没想完了,我真的不知道在这种情况下会出现什么问题。我想知道是否有人经历过这个问题可能会让我失望?
由于代码很长,我只提取主要功能:
这是我的User class
数据:
public class FriendFeed {
// required parameters
private final int activityId; // in case we want to handle the detail of
// this activity
private final int friendId;
private final String friendName;
private final Challenge.Type challengeType;
private final String activityTime;
private final String placeName;
// optional parameter
private String challengeName;
private String challengeDescription;
private Uri activitySnapPictureUri = null;
private Uri friendPictureUri = null;
private String activityComment;
这是我的主要功能:
@Override
protected Boolean doInBackground(Void...voids) {
JSONArray array = JsonHelper.getJsonArrayFromUrlWithData(GET_FRIEND_FEED_URL, datas);
if (array != null) {
try {
for (int i = 0; i < array.length(); ++i) {
Uri snapPictureUri = null;
Uri userPictureUri = null;
if (Challenge.returnType(array.getJSONObject(i).getString("challenges_tbl_type")) == Challenge.Type.SNAP_PICTURE) {
snapPictureUri = constructUriFromBitmap(ImageHelper.downloadImage(array.getJSONObject(i).getString("activity_tbl_snap_picture_url")));
}
if(ImageHelper.downloadImage(array.getJSONObject(i).getString("users_tbl_user_image_url")) != null) {
userPictureUri = constructUriFromBitmap(ImageHelper.downloadImage(array.getJSONObject(i).getString("users_tbl_user_image_url")));
}
publishProgress(
new FriendFeed.Builder(
// required parameters
array.getJSONObject(i).getInt("activity_tbl_id"),
array.getJSONObject(i).getInt("friends_tbl_friend_id"),
array.getJSONObject(i).getString("users_tbl_username"),
Challenge.returnType(array.getJSONObject(i).getString("challenges_tbl_type")),
array.getJSONObject(i).getString("activity_tbl_created"),
array.getJSONObject(i).getString("spots_tbl_name"))
// optional parameters
.challengeName(array.getJSONObject(i).getString("challenges_tbl_name"))
.challengeDescription(array.getJSONObject(i).getString("challenges_tbl_description"))
.activitySnapPictureUri(snapPictureUri)
.friendPictureUri(userPictureUri)
.activityComment(array.getJSONObject(i).getString("activity_tbl_comment"))
.build());
}
}
catch (JSONException e) {
Log.e(TAG + "GetFriendFeedTask.doInBackGround(Void ...voids) : ", "JSON error parsing data" + e.toString());
}
return true;
}
else {
return false;
}
}
答案 0 :(得分:1)
Android强制执行每个进程的内存分配限制为24MB,因此您无法分配更多内容。但是,每张70K的20张照片应该只有1.4MB ...所以我的猜测:
也许您在应用的其他部分分配了位图,因此此ListView上的位图可用的内容少于1.4MB。
某处内存泄漏
如果你确定你确实需要你正在使用的所有位图,你确定你需要这么大的位图还是有这么大的分辨率?减少它们可以提供帮助。
如果所有其他方法都失败并且您确实需要大量内存中的位图,则可以始终使用OpenGL纹理。