gpt4 book ai didi

android - VM 在从缓存中获取图像时内存不足

转载 作者:行者123 更新时间:2023-11-29 18:18:53 27 4
gpt4 key购买 nike

已知我要解决的问题存在于具有 16 MB 堆内存的设备中,我需要解决它。我有线程从服务器(大图像)获取图像并将它们缓存然后显示。问题是我内存不足。为了进一步解释,我发布了我的日志猫以及一些代码:

public class Test extends Activity implements OnClickListener {
ImageView paint, wheels, shadow;

Button b;
int j = 2;
int i = 1;
String pathToWheels, pathToPaint, pathToShadow;
String stringAngle;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

MemoryInfo dbm = new MemoryInfo();
Debug.getMemoryInfo(dbm);
b = (Button) findViewById(R.id.button1);
b.setOnClickListener(this);



wheels = (ImageView) findViewById(R.id.imageView3);
paint = (ImageView) findViewById(R.id.imageView2);
shadow = (ImageView) findViewById(R.id.imageView1);



while (i < 13) {

stringAngle = Integer.toString(i);
String pathToWheels = url;
String pathToPaint = url;
String pathToShadow = url;

if (Cache.getCacheFile(pathToWheels) == null) {
ImageDownloader downloader1 = new ImageDownloader(wheels);
downloader1
.execute(url);
} else if (Cache.getCacheFile(pathToShadow) == null) {
ImageDownloader downloader2 = new ImageDownloader(shadow);
downloader2
.execute(url);


} else if (Cache.getCacheFile(pathToPaint) == null) {

ImageDownloader downloader = new ImageDownloader(paint);
downloader
.execute(url);


}

i++;


}

}



@Override
protected void onPause() {
super.onPause();
Toast.makeText(getApplicationContext(),"Pause",
Toast.LENGTH_SHORT).show();

}

@Override
public void onClick(View v) {


if (v.getId() == R.id.button1) {
if (j == 13)
{
j = 1;
}
String s = Integer.toString(j);
wheels.setImageBitmap(Cache
.getCacheFile(url));
paint.setImageBitmap(Cache
.getCacheFile(url));
shadow.setImageBitmap(Cache
.getCacheFile(url));
j++;



}
}

来 self 的缓存类:

public static void saveCacheFile(String cacheUri, Bitmap image) {
if(!isCacheWritable()) return;
Log.i("CACHE S",cacheUri);
cache.saveCacheFile(cacheUri, image);

来 self 的 CacheStore 类:

public Bitmap getCacheFile(String cacheUri) {
if(bitmapMap.containsKey(cacheUri)) return (Bitmap)bitmapMap.get(cacheUri);

if(!cacheMap.containsKey(cacheUri)) return null;
String fileLocalName = cacheMap.get(cacheUri);
File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
File fileUri = new File(fullCacheDir.toString(), fileLocalName);
if(!fileUri.exists()) return null;
Log.i("CACHE", "File "+cacheUri+" has been found in the Cache");
Bitmap bm = BitmapFactory.decodeFile(fileUri.toString());
Bitmap.createScaledBitmap(bm, 480, 320, true);
bitmapMap.put(cacheUri, bm);
return bm;
}

应用程序在这一行崩溃:Bitmap bm = BitmapFactory.decodeFile(fileUri.toString());我内存不足的地方。

我的日志:

    07-06 23:40:20.720: ERROR/dalvikvm-heap(1844): 691200-byte external allocation too large for this process.
07-06 23:40:20.720: ERROR/GraphicsJNI(1844): VM won't let us allocate 691200 bytes
07-06 23:40:20.770: DEBUG/skia(1844): --- decoder->decode returned false
07-06 23:40:20.790: DEBUG/AndroidRuntime(1844): Shutting down VM
07-06 23:40:20.830: WARN/dalvikvm(1844): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): FATAL EXCEPTION: main
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:271)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:296)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at com.cache.CacheStore.getCacheFile(CacheStore.java:117)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at com.cache.Cache.getCacheFile(Cache.java:38)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at com.cache.Test.onClick(Test.java:118)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.view.View.performClick(View.java:2408)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.view.View$PerformClick.run(View.java:8816)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.os.Handler.handleCallback(Handler.java:587)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.os.Handler.dispatchMessage(Handler.java:92)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.os.Looper.loop(Looper.java:123)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at java.lang.reflect.Method.invokeNative(Native Method)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at java.lang.reflect.Method.invoke(Method.java:521)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-06 23:40:20.890: ERROR/AndroidRuntime(1844): at dalvik.system.NativeStart.main(Native Method)

如有任何帮助,我们将不胜感激,感谢阅读。

最佳答案

您需要在将位图插入到图像下载器内的缓存中之前对其进行重新采样和缩放。

过去,我必须在从网络下载图像之前检测图像的文件大小。如果它太大,我就使用默认图像。

此外,我还通过调整 BitmapFactory Sampling 大小降低了保存图像的分辨率,并在您的应用中调整了最终图像的大小。 (这为缓存节省了很多空间)。

参见 How to know the size of a file before downloading it?

//somewhere inside image downloader class...
{...}

BitmapFactory.Options options = new BitmapFactory.Options();

if(enableSampling)
options.inSampleSize = 2;

returnBitmap = BitmapFactory.decodeStream(is, null, options);

if(returnBitmap != null)
{

if(scaleImage)
returnBitmap = Bitmap.createScaledBitmap(returnBitmap, width, height, true);

// insert the image into the cache
imageCache.put(url, new SoftReference<Bitmap>(returnBitmap));


// Check the ImageView for nulls
if(imageView != null && callback != null){
ImageDisplayer displayer = new ImageDisplayer(imageView, returnBitmap, parentView, tag);
callback.onImageReceived(displayer);
}

}

{...}

到目前为止,这对我有用,检查 INSANE 文件大小使应用程序免于多次崩溃,更不用说它可以跳过在后台下载大量文件。

关于android - VM 在从缓存中获取图像时内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6604362/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com