2011-07-06 12 views
1

私が対処している問題は、16 MBのヒープメモリを持つデバイスであることが知られており、解決する必要があります。私はスレッド(ビッグイメージ)サーバーからのイメージを取得し、キャッシュされて表示されている。問題は、私の記憶がなくなってしまうことです。キャッシュからイメージを取得中にVMが不足する

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++; 



    } 
} 

}

私のキャッシュクラスから::

:私のCacheStoreクラスから

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

私は私のログの猫を掲示していますさらに少しだけでなく、いくつかのコードを説明するために、

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()); 私はメモリが不足しています。

マイlogcat:任意の助けをいただければ幸いです

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) 

、読んでくれてありがとう。

答えて

2

をチェックしてください。

以前は、Webからダウンロードする前に画像のファイルサイズを検出しなければなりませんでした。大きすぎる場合は、デフォルトの画像を使用します。

また、BitmapFactoryサンプリングサイズを調整して保存画像の解像度を下げ、アプリで最終画像のサイズを調整しました。 (これにより、キャッシュのために多くのスペースが節約されました)。

はこれまでのところ、これは私のために働いてい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ファイルサイズのチェックが何度もクラッシュからアプリを保存している、それだけで大規模なファイルをdownloaingスキップすることができます言うまでもありません背景。

+0

私はクラッシュが起こった場所を編集して申し訳ありませんが、本当に助けに感謝します。また、EnableSamplingとscaleImageに関してもう少し明示的にすることができますか? –

+0

これらの2つの値は、ただちにその機能を無効にできるようにしたいブール値です。イメージがヘッダーファイルで検出されたサイズで十分に小さく、サイズを変更する必要がない場合は、再サンプリングせずに拡大縮小もしません。 –

1

あなたは、サンプルを再度、あなたimagedownloaderの内側に、キャッシュに挿入するには、あなたのビットマップを拡張する必要がBitmapFactory OOM driving me nuts

関連する問題