【问题标题】:Run out of memory when posting photo to database android将照片发布到数据库android时内存不足
【发布时间】:2016-06-04 12:14:10
【问题描述】:

我正在尝试使用 volley 将照片发送到我的数据库,将 byte[] 转换为 String。这是我调用凌空方法并从ImageView 内的图像中获取String 的地方:

addPic.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ImageView pic_holder = (ImageView) findViewById(R.id.picturedisplay);
            Bitmap bitmap = ((BitmapDrawable)pic_holder.getDrawable()).getBitmap();
            ByteArrayOutputStream stream=new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
            byte[] image=stream.toByteArray();
            String img_str = Base64.encodeToString(image, 0);
            MyLocation myLocation = new MyLocation();
            myLocation.getLocation(getApplicationContext(), locationResult);
            boolean r = myLocation.getLocation(getApplicationContext(),
                    locationResult);
            if (!r) {
                AlertDialog.Builder builder1 = new AlertDialog.Builder(getApplicationContext());
                builder1.setMessage("Please enable your GPS.");
                builder1.setCancelable(false);
                builder1.setPositiveButton(
                        "Ok",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                            }
                        });

                AlertDialog alert11 = builder1.create();
                alert11.show();
            }
            else {
                savePhoto(Latitude,Longitude,username,picText,img_str);
            }

这是我的截击方法:

public void savePhoto(final Double latitude, final Double longitude, final String username, final String description,final String picture ) {
    pDialog.setMessage("Posting picture..");
    pDialog.show();

    request = new StringRequest(Request.Method.POST, SL_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String s) {
            pDialog.dismiss();
                    Toast.makeText(getApplicationContext(),
                            "Your picture has been posted.", Toast.LENGTH_LONG).show();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {

        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("latitude", Double.toString(latitude));
            hashMap.put("longitude", Double.toString(longitude));
            hashMap.put("image",picture);
            hashMap.put("user", username);
            hashMap.put("description", description);
            return hashMap;
        }
    };
    queue.add(request);
}

LOGCAT:

02-22 21:33:54.350 5233-5240/citylife.com.city W/art: Suspending all threads took: 17.926ms
02-22 21:33:58.310 5233-5233/citylife.com.city I/Choreographer: Skipped 707 frames!  The application may be doing too much work on its main thread.
02-22 21:33:59.090 5233-5233/citylife.com.city D/DisplayManager: DisplayManager()
02-22 21:34:01.860 5233-5240/citylife.com.city W/art: Suspending all threads took: 11.464ms
02-22 21:34:05.360 5233-5240/citylife.com.city W/art: Suspending all threads took: 6.127ms
02-22 21:34:06.350 5233-5248/citylife.com.city W/art: Suspending all threads took: 100.142ms
02-22 21:34:06.390 5233-5240/citylife.com.city W/art: Suspending all threads took: 32.192ms
02-22 21:34:06.410 5233-5276/citylife.com.city I/art: Alloc partial concurrent mark sweep GC freed 16(496B) AllocSpace objects, 1(25MB) LOS objects, 11% free, 60MB/68MB, paused 962us total 53.527ms
02-22 21:34:06.410 5233-5248/citylife.com.city I/art: WaitForGcToComplete blocked for 53.981ms for cause Background
02-22 21:34:06.490 5233-5276/citylife.com.city I/art: WaitForGcToComplete blocked for 9.452ms for cause Alloc
02-22 21:34:06.500 5233-5276/citylife.com.city I/art: Alloc sticky concurrent mark sweep GC freed 1(32B) AllocSpace objects, 0(0B) LOS objects, 9% free, 79MB/87MB, paused 1.008ms total 7.842ms
02-22 21:34:06.530 5233-5276/citylife.com.city I/art: Alloc partial concurrent mark sweep GC freed 8(256B) AllocSpace objects, 1(18MB) LOS objects, 11% free, 60MB/68MB, paused 1.099ms total 26.534ms
02-22 21:34:06.570 5233-5248/citylife.com.city W/art: Suspending all threads took: 39.015ms
02-22 21:34:06.610 5233-5276/citylife.com.city I/art: Alloc partial concurrent mark sweep GC freed 7(224B) AllocSpace objects, 1(18MB) LOS objects, 10% free, 70MB/78MB, paused 940us total 29.766ms
02-22 21:34:06.690 5233-5276/citylife.com.city I/art: Clamp target GC heap from 96MB to 96MB
02-22 21:34:06.690 5233-5276/citylife.com.city I/art: Alloc partial concurrent mark sweep GC freed 6(192B) AllocSpace objects, 0(0B) LOS objects, 7% free, 88MB/96MB, paused 1.176ms total 18.263ms
02-22 21:34:06.700 5233-5276/citylife.com.city I/art: Alloc sticky concurrent mark sweep GC freed 2(64B) AllocSpace objects, 0(0B) LOS objects, 7% free, 88MB/96MB, paused 956us total 7.052ms
02-22 21:34:06.750 5233-5276/citylife.com.city I/art: Clamp target GC heap from 96MB to 96MB
02-22 21:34:06.750 5233-5276/citylife.com.city I/art: Alloc concurrent mark sweep GC freed 12(12KB) AllocSpace objects, 0(0B) LOS objects, 7% free, 88MB/96MB, paused 972us total 50.996ms
02-22 21:34:06.750 5233-5276/citylife.com.city I/art: Forcing collection of SoftReferences for 9MB allocation
02-22 21:34:06.780 5233-5276/citylife.com.city I/art: Clamp target GC heap from 96MB to 96MB
02-22 21:34:06.780 5233-5276/citylife.com.city I/art: Alloc concurrent mark sweep GC freed 13(408B) AllocSpace objects, 0(0B) LOS objects, 7% free, 88MB/96MB, paused 1.060ms total 28.205ms
02-22 21:34:06.780 5233-5276/citylife.com.city E/art: Throwing OutOfMemoryError "Failed to allocate a 9606684 byte allocation with 8049319 free bytes and 7MB until OOM"
02-22 21:34:06.800 5233-5276/citylife.com.city E/AndroidRuntime: FATAL EXCEPTION: Thread-3159
                                                                 Process: citylife.com.city, PID: 5233
                                                                 java.lang.OutOfMemoryError: Failed to allocate a 9606684 byte allocation with 8049319 free bytes and 7MB until OOM
                                                                     at java.nio.charset.Charsets.toUtf8Bytes(Native Method)
                                                                     at java.lang.String.getBytes(String.java:775)
                                                                     at java.lang.String.getBytes(String.java:759)
                                                                     at com.android.volley.Request.encodeParameters(Request.java:452)
                                                                     at com.android.volley.Request.getBody(Request.java:435)
                                                                     at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:236)
                                                                     at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:210)
                                                                     at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:106)
                                                                     at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
                                                                     at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)

【问题讨论】:

  • 您要么需要将图像缩小一些,要么分块发送图像(我不知道 volley 是否支持)
  • 你能给我一个如何缩小图像的例子吗?
  • 我设法让它现在发送,但是我收到了这个错误com.android.volley.NoConnectionError: java.net.SocketException: sendto failed: EPIPE (Broken pipe)

标签: java android imageview bytearray android-volley


【解决方案1】:

使用位图要非常小心,因为它们非常大并且会出现此错误。 在清单文件的应用程序标记中使用android:largeHeap="true" 对我有用,因为您最初有更多空间,但这仍然不能 100% 解决问题,所以只需尝试最小化内存的使用,创建位图,使用它,并摆脱它,因此尽量不要将它们存储到列表或地图中。

【讨论】:

  • 您建议我如何将照片发送到数据库?它被发送到服务器上的 php 脚本,该脚本将其插入 mysqli 数据库
  • 我会说如果可以的话,请立即发送,检查本地数据库中的内容并将它们发送到服务器,这样您就不会将它们放入内存中。
  • 如果图像来自设备存储。您可以将图像作为文件发送到服务器。使用 loopj asynchttpclient 库而不是 volley。很容易。
  • @SreeAndroidDev 基本上我用相机拍照,在图像视图中显示在屏幕上,用户可以选择将其存储在手机中但不必,然后当他按下发送按钮将其发送到服务器,他还可以选择删除它,并且照片不会存储在任何地方。这是我想要实现的行为,所以如果他不选择将其保存在手机上,我就无法真正从存储中获取它。
  • 好的,这样一来你的内存中只有一个图像,所以你应该没问题,不需要存储任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
相关资源
最近更新 更多