- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试创建一个用于从服务器下载图像并将其显示到 ListView 中的应用程序。我造成的问题是内存泄漏并使我的应用程序崩溃。我在 Android 博客中搜索这样的 link ,它显示了一个好主意,但它仍然不足以用多线程来完成。 android的一些设备可以使用它,但有些设备只能在单线程中处理,有时根本无法工作。
我的应用程序有很多 Activity ,每个 Activity 都有一个 ListView ,需要尽可能快地显示图像。通过 Google IO 2012,他们使用缓冲区将原始图像保存到 SD 卡,它解决了内存泄漏问题,但由于需要下载的图像太大,加载速度很慢。
我的问题是:有没有什么方法可以在将图像写入 SD 卡的同时缩放图像?我发现一些可能的解决方案是在输入流对象中使用 Skip byte,并且我能够找到我需要下载的图像的每像素宽度和高度。
以下代码在 Google IO 2012 中使用,它适用于多线程,在我的例子中,我有 4 个线程在后台运行。
private void downloadAndWriteFile(final String url, final File file) throws OutOfMemoryError {
BufferedOutputStream out = null;
try {
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setDoInput(true);
conn.connect();
final InputStream in = new BufferedInputStream(conn.getInputStream(), IO_BUFFER_SIZE_BYTES); // buffer size 1KB
out = new BufferedOutputStream(new FileOutputStream(file), IO_BUFFER_SIZE_BYTES);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
out.close();
conn.disconnect();
}
catch (Exception e) {
Log.e(TAG, "!!downloadAndWriteFile " + e.getMessage());
file.delete();
}
}
最佳答案
1) 在设置图像之前使用以下代码释放与此位图关联的 native 对象,并清除对像素数据的引用。如果没有其他引用,它只是允许对其进行垃圾回收。
BitmapDrawable drawable = (BitmapDrawable) myImage.getDrawable();
Bitmap bitmap = drawable.getBitmap();
if (bitmap != null)
{
bitmap.recycle();
}
2) 使用此方法减小位图在内存中的大小:
/**
* decodes image and scales it to reduce memory consumption
*
* @param file
* @param requiredSize
* @return
*/
public static Bitmap decodeFile(File file, int requiredSize) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(file), null, o);
// The new size we want to scale to
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < requiredSize
|| height_tmp / 2 < requiredSize)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(file),
null, o2);
return bmp;
} catch (FileNotFoundException e) {
} finally {
System.gc();
}
return null;
}
关于java - Android从服务器下载图像并保存到sdcard而不使用BitmapFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12329136/
通过使用方法 BitmapFactory.decodeStream(Resources res,int id) 和 BitmapFactory.decodeFile(String pathName)
我的应用程序从 SD 卡解码大量位图,因此我想重用现有位图以减少 GC 工作。我看到来自 Android Training 的示例和 this video它非常适合 BitmapFactory.dec
哪种设置 ImageView 图像的方法更好(使用更少的堆空间)? imageView.setImageDrawable(Drawable.createFromPath(path)); 或
我在向 gridview 添加可变背景时遇到 OutOfMemoryError...在 final Bitmap shelfBackground = BitmapFactory.decodeResou
url="http://www.nasa.gov/sites/default/files/styles/946xvariable_height/public/ladee_spin_2_in_motio
我打算编写一个小画廊应用程序。所以我有一个带有图像的 gridview,显示的图像被存储在本地设备上。我得到的是一个类 ImageLoader,它在后台线程 (AsyncTask) 中加载特定路径中的
在我的应用程序中,我有一个文件: private File TEMP_PHOTO_FILE = new File(Environment.getExternalStorageDirectory(),
您好,我正在从名为 image.png 的 png 图像创建位图。图像的尺寸为 75(宽)x 92(高)。当我运行这段代码时: Bitmap bitmap = BitmapFactory.decode
在我的 android 应用程序中,我上传和下载 JPEG 图像。对于某些图像,BitmapFactory 对下载的图像进行下采样,我不明白为什么以及如何阻止它这样做。我在上传和下载图像时记录位图对象
我有同一张图片的两份副本。其中一个在应用程序的资源文件夹(默认可绘制对象)中,另一个在外部存储中。 我用以下代码得到了位图: // Get from storage BitmapFactory.d
嘿,我不确定为什么每次我在图库中选择图片时都会出现这个问题? 代码如下: if (v == uploadImageButton) { // below
今天我的应用程序崩溃了,出现内存不足错误。 java.lang.OutOfMemoryError in android.graphics.BitmapFactory.nativeDecodeAsset
我正在尝试从Camera.PictureCallback onPictureTaken获取Jpeg,但是当我这样做时 bitmapImage = BitmapFactory.decodeByteArr
在研究 Android 的 BitmapFactory.Options 类时,我注意到它的字段是公开可以访问和修改的。 这与一般封装规则相反,该规则规定字段应声明为 private,并且应通过 pub
这段代码给出了运行时异常,我无法捕获它。 BitmapFactory.decodeByteArray 不会返回 null 或类似的内容。 Bitmap bitmap = BitmapFactory.d
我有一个包含两列的 ArrayList,并显示下面带有文本的图像。我正在使用高质量图像,并且需要在 GridView 中以良好的质量显示这些图像,为此我使用 BitmapFactory.Options
我应该从互联网获取图像并将其显示在我的 Activity 中。为此,我使用 asynctask 类。我忘记在我的 list 文件中提及互联网权限,并且应用程序成功运行,没有给出任何异常,并且能够获取模
如何从字节数组构造原始大小的位图? byte[] imageAsBytes = Base64.decode(b64.getBytes(), Base64.DEFAULT); Bitma
我在这里从 Cursor 获取值: if (mProfileCursor.moveToFirst()) { byte[] blob = mProfileCursor.getBl
我正在尝试使用这个: BitmapFactory.decodeFile("logo.jpg") 与我的 apk 相比,我似乎没有将文件:logo.jpg 放在正确的位置。它应该去哪里? 附言我得到的错
我是一名优秀的程序员,十分优秀!