Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android ViewFlipper:OutOfMemoryError:位图大小超出VM预算_Android_Viewflipper_Out Of Memory - Fatal编程技术网

Android ViewFlipper:OutOfMemoryError:位图大小超出VM预算

Android ViewFlipper:OutOfMemoryError:位图大小超出VM预算,android,viewflipper,out-of-memory,Android,Viewflipper,Out Of Memory,我正在android应用程序中使用ViewFlipper。调用StartLipping()后,如果让应用程序运行几分钟,很快就会出现错误: 11-22 15:36:34.354: ERROR/dalvikvm-heap(428): 307200-byte external allocation too large for this process. 11-22 15:36:34.372: ERROR/(428): VM won't let us allocate 307200 bytes 11-

我正在android应用程序中使用ViewFlipper。调用StartLipping()后,如果让应用程序运行几分钟,很快就会出现错误:

11-22 15:36:34.354: ERROR/dalvikvm-heap(428): 307200-byte external allocation too large for this process.
11-22 15:36:34.372: ERROR/(428): VM won't let us allocate 307200 bytes
11-22 15:36:34.375: ERROR/AndroidRuntime(428): Uncaught handler: thread main exiting due to uncaught exception
11-22 15:36:34.384: ERROR/AndroidRuntime(428): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:271)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:296)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist.populate(ViewPlaylist.java:115)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist.access$0(ViewPlaylist.java:100)
11-22 15:36:34.384: ERROR/AndroidRuntime(428):     at com.PlayerOrange.ViewPlaylist$ProgressTask$1$1.run(ViewPlaylist.java:383)
每30秒我就会得到一些关于内存的信息,如下所示:

ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(ACTIVITY_SERVICE);
                android.app.ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
                activityManager.getMemoryInfo(memoryInfo);

                Log.i(TAG, " memoryInfo.availMem " + memoryInfo.availMem + "\n" );
                Log.i(TAG, " memoryInfo.lowMemory " + memoryInfo.lowMemory + "\n" );
                Log.i(TAG, " memoryInfo.threshold " + memoryInfo.threshold + "\n" );
奇怪的是,在强制关闭(outofmemoryError)之前,我在DDMS中有以下内容:

11-22 15:36:10.255: INFO/(428):  memoryInfo.availMem 50470912
11-22 15:36:10.255: INFO/(428):  memoryInfo.lowMemory false
11-22 15:36:10.264: INFO/(428):  memoryInfo.threshold 16777216
我不知道如何解决这个错误

下面是我填充
查看翻转器的代码:

private void populate() {
        for (int i = 0; i < jArray.length(); i++) {
            System.out.println("lungime" + jArray.length());
            LinearLayout l = new LinearLayout(this);
            l.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT));
            l.setBackgroundColor(0x000000);
            l.setOrientation(LinearLayout.VERTICAL);
            vf.addView(l);

            File f = new File(Environment.getExternalStorageDirectory()
                    + "/Downloads/");

            File[] files = f.listFiles();

            Bitmap bitmap = BitmapFactory.decodeFile(files[i].getPath());
            img = new ImageView(this);
            img.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT));

            img.setImageBitmap(bitmap);

            System.out.println("target " + target[i]);
            img.setOnTouchListener(this);
            img.setId(i);

            l.addView(img);
            img = null;

        }
我从网络上获取图像并保存到SD卡。之后,我从SD卡的文件夹中获取它们,并将它们添加到viewFlipper

任何想法都欢迎。提前谢谢

  • 使用一些缓存机制来减少内存使用
  • 使用BitmapFactory.Options缩小图像的比例
  • 这里的缓存意味着使用某种数据结构来保持对图像的有效引用。这只意味着您可以根据需要通过缓存访问图像,而缓存将尝试根据需要仅保留对所需图像的引用。这通常通过使用
    SoftReference
    完成: 甚至
    WeakReference


    下面是一个例子:

    与以下内容相关,专家已经对其进行了提问和回答

    OutOfMemoryError:位图大小超过VM预算

    查看以下链接:


    您只是使用了太多太大的位图图像

    如果一次内存中有太多图像,则会导致OutOfMemoryException,因为位图实际上只是巨大的二维数组

    正如在另一个答案中所说的,您可以做两件不同的事情:减小图像的大小或一次减少内存中的图像量

    可以使用缓存或弱引用,也可以动态缩小位图。这些都是比较先进的技术。如果可能的话,最好是使用更小的位图作为源

    如果不能,这里有一个简单的解决方案:

            img.setImageBitmap(bitmap);
            bitmap.recycle();
            System.out.println("target " + target[i]);
    

    这样可以更迅速地清除位图对象。更多信息,请参见以下内容:。

    @Gabrielle,我在上面的回答中添加了一些解释。5分钟后,即使我使用了SoftReference,我仍然可以使用强制关闭:|嗨,格雷姆,当我按照你的说法尝试时,然后我得到了这个错误:Canvas:尝试使用回收的位图android.graphics.bitmap你能给出任何建议吗?…一旦你回收了位图,它就会被垃圾收集销毁和清理,它的内存会被释放以供重用。一旦回收,它就不再可用。你说得对,但是…我的代码类似于…:File folder=new File(GlobalPhotoPrivacy.savedImagesFolderPath+“/”+rowId);File[]files=文件夹.listFiles();for(int i=0;iYou应该在位图加载到页面后循环使用它。我首先将所有ImageView加载到寻呼机中,然后使用for循环将所有ImageView加载到后台线程中,我将位图设置为它,设置后我将循环使用它…哪里会出错?
            img.setImageBitmap(bitmap);
            bitmap.recycle();
            System.out.println("target " + target[i]);