【问题标题】:Android - Repeatedly Created Bitmaps causes failureAndroid - 重复创建位图导致失败
【发布时间】:2013-11-08 15:22:57
【问题描述】:

A1: 在应用程序中,我加载服务器的 4 base64 字符串并在应用程序中创建缩略图。 为它们创建视图并将它们添加到滚动布局中。 目前没有问题。

A1-A1-A1++ 如果我一次又一次地重复 A1 - 在布局中添加 5 个图像和 5 个更多图像...... - 没问题。

A2: 仍在应用程序中 - 转到主要活动。 进入一项新活动 - 图片选择活动。 从应用程序选择部分的图库中加载图像。 创建图像预览。 目前没有问题。

A2-A2-A2++ 如果我在此之后一次又一次地重复 A2 - 没问题。

A1-A2-A2-A2++ 如果我做 A1 并一次又一次地重复 A2 - 没问题。

A1-A2-A1-A2 如果我从 A1 开始执行 A2 并返回 A1 然后 A2,它应该在创建预览图像时崩溃。

A1:

     int count = 1;
        while (count < 5)
           {


                try {


                    TelephonyManager mngr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 
                    String imei = mngr.getDeviceId();
                    String image_count = String.valueOf(count);
                    String user_image = new GetUserImagesActivity().execute(imei,image_count).get();                                                                
                    byte[] decodedString = Base64.decode(user_image, Base64.DEFAULT);
                    Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
                    /*BitmapDrawable ob = new BitmapDrawable(decodedByte);*/        



                //ImageView Setup
                ImageView imageView1 = new ImageView(this);
                imageView1.setTag(count);
                imageView1.setOnTouchListener(this);
                //setting image resource
                imageView1.setImageBitmap(decodedByte);
                //setting image position        

                LinearLayout.LayoutParams params2 = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                params2.gravity=Gravity.CENTER_HORIZONTAL;
                params2.gravity=Gravity.CENTER_VERTICAL;            
                imageView1.setLayoutParams(params2);                       


                imageView1.setAdjustViewBounds(true);
                imageView1.setMaxHeight(240);
                imageView1.setMaxWidth(180);
                /*imageView.setMinimumHeight(180);
                imageView.setMinimumWidth(240);*/
                imageView1.setId(110011);
                imageView1.setPadding(5, 0, 5, 0);
                //adding view to layout
                top_container.addView(imageView1);

                count++;

   //Tried this to solve the problem//
                imageView1.setDrawingCacheEnabled(true);
                imageView1.buildDrawingCache();

                //Causes images to get black//
                /*decodedByte.recycle();*/

               } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                Toast.makeText( getApplicationContext(), "problem 1" , Toast.LENGTH_LONG ).show();  
            } catch (ExecutionException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                Toast.makeText( getApplicationContext(), "problem 2" , Toast.LENGTH_LONG ).show();
            }

           }

A2:- 新图像到服务器(预览失败)

                cursor.moveToFirst();
                int idx = cursor.getColumnIndex(ImageColumns.DATA);
                String fileSrc = cursor.getString(idx);

                bitmap = BitmapFactory.decodeFile(fileSrc);
                // load  // preview  // image
                bitmap = Bitmap.createScaledBitmap(bitmap, 480, 640, false);
                // bmpDrawable = new BitmapDrawable(bitmapPreview);
                img_logo.setImageBitmap(bitmap);

日志:

        11-08 16:44:58.293: D/dalvikvm(22771): GC_BEFORE_OOM freed 44K, 34% free 22390K/33571K, paused 23ms

        11-08 16:44:58.293: E/dalvikvm-heap(22771): Out of memory on a 36000016-byte allocation.  

        11-08 16:44:58.303: W/dalvikvm(22771): threadid=1: thread exiting with uncaught exception (group=0x40a9f210)

        11-08 16:44:58.303: E/AndroidRuntime(22771): FATAL EXCEPTION: main

        11-08 16:44:58.303: E/AndroidRuntime(22771): java.lang.OutOfMemoryError

        11-08 16:44:58.303: E/AndroidRuntime(22771):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)

        11-08 16:44:58.303: E/AndroidRuntime(22771):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)

        11-08 16:44:58.303: E/AndroidRuntime(22771):    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:305)

【问题讨论】:

  • 崩溃时的堆栈跟踪是什么?
  • 在我的测试手机上运行代码,因为 eclipse 在取笑我。我可以包括一个堆栈跟踪和“吐司”吗?
  • 当您在启用 USB 调试的情况下运行它时,它会将崩溃堆栈跟踪打印为红色的 logcat。
  • 好的,请赐教..因为我看不到/不知道我应该从哪里得到这个?
  • 好的.. 我真的看到我在那里错过了很多信息。它导致内存不足。

标签: android bitmap base64 decode encode


【解决方案1】:

不使用位图类,而是使用 Wea​​kReference 类;

喜欢 而不是这一行。

bitmap = BitmapFactory.decodeFile(fileSrc);

使用这个。

WeakReference<Bitmap> bitmap=new WeakReference<Bitmap>(BitmapFactory.decodeFile(fileSrc));

WeakReference 是 android 中的特殊类型,它可以快速清除内存中的其他对象。

【讨论】:

  • 这会导致 CreateScaledBitmap 和 setImageBitmap 出现错误 - Eclipse 想要将部分更改为没有意义的内容.. ?
【解决方案2】:

内存不足错误意味着:您没有足够的内存来加载更多位图。

可能的解决方案:

只保留最大数量的图片的缓存。

和/或通过 BitmapFactory 加载图片时减小 inSampleSize

尝试阅读:Displaying Bitmaps Effeciently

【讨论】:

  • 我预计会是这种情况 - 因为一切都可以自行运行 - 自己的活动反复没有崩溃,我确实知道这个文档,但我没有看到与什么直接相关的东西我在做。
  • 让我重新措辞。我没有看到对在哪里以及为什么有帮助的解释。正如你从我的代码中看到的,我已经准备好尝试回收图像和缓存图像,因为我知道我正在淹没内存。我没有重复使用图像,所以如果我可以刷新一个活动@活动更改中存在的所有图像,这就是我要寻找的。​​span>
  • 您是否在解码位图时降低了 inSampleSize,当活动发生变化时,您可以在所有位图上调用 recycle() 以尽快释放它们的内存
  • 调用回收不是动态加载图像的解决方案,因为它们没有在“可用”区域内定义..我在这方面经验不足。在新的图像选择活动中,我在活动更改时添加了 recycle(),在活动更改时关闭 bytearrayoutputstream,在创建预览图像时添加 inSampleSize。看来这成功了。
  • 我在代码中添加了 3 样东西,现在不能让它崩溃!
【解决方案3】:

解决方案是:

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

                options.inDither = false;
                options.inSampleSize = 6;
                bitmap = BitmapFactory.decodeFile(fileSrc,options);                                                                                                    

                img_logo.setImageBitmap(bitmap);

我还添加了 bao.close();和 bitmap.recycle();这在制作base64图像字符串并关闭活动时:代码如下:

        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 30, bao);
        byte[] ba = bao.toByteArray();
        String text = Base64.encodeToString(ba,0);
        try {
            bao.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        bitmap.recycle();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 2016-04-13
    • 1970-01-01
    • 2019-05-25
    • 2015-11-14
    相关资源
    最近更新 更多