无法理解此堆栈跟踪(parse.com)

Unable to understand this stack trace(parse.com)

我在我的应用程序中使用了 crashylytics。它已经投入生产大约 2 个月。我遇到了一些我已经能够解决的崩溃,但是最近几天我得到了一个堆栈跟踪,它没有指向我的代码中的一行(甚至 activity),此时崩溃发生了。

Fatal Exception: java.lang.OutOfMemoryError
       at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:120)
       at org.apache.http.conn.BasicManagedEntity.eofDetected(BasicManagedEntity.java:161)
       at org.apache.http.conn.EofSensorInputStream.checkEOF(EofSensorInputStream.java:239)
       at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:179)
       at com.parse.ParseIOUtils.copyLarge(ParseIOUtils.java:129)
       at com.parse.ParseIOUtils.copyLarge(ParseIOUtils.java:106)
       at com.parse.ParseIOUtils.copy(ParseIOUtils.java:81)
       at com.parse.ParseIOUtils.toByteArray(ParseIOUtils.java:55)
       at com.parse.ParseRESTObjectBatchCommand.onResponse(ParseRESTObjectBatchCommand.java:66)
       at com.parse.ParseRequest.then(ParseRequest.java:229)
       at com.parse.ParseRequest.then(ParseRequest.java:225)
       at bolts.Task.run(Task.java:486)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
       at bolts.Task.completeAfterTask(Task.java:482)
       at bolts.Task.continueWithTask(Task.java:358)
       at bolts.Task.continueWithTask(Task.java:369)
       at bolts.Task.then(Task.java:415)
       at bolts.Task.then(Task.java:407)
       at bolts.Task.run(Task.java:486)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)

还有这个。

Fatal Exception: java.lang.OutOfMemoryError
       at org.apache.http.util.ByteArrayBuffer.<init>(ByteArrayBuffer.java:53)
       at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:82)
       at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:70)
       at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
       at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
       at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
       at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
       at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:172)
       at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
       at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
       at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:587)
       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:511)
       at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:489)
       at com.parse.ParseApacheHttpClient.execute(ParseApacheHttpClient.java:97)
       at com.parse.ParseRequest.then(ParseRequest.java:228)
       at com.parse.ParseRequest.then(ParseRequest.java:225)
       at bolts.Task.run(Task.java:486)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
       at bolts.Task.completeAfterTask(Task.java:482)
       at bolts.Task.continueWithTask(Task.java:358)
       at bolts.Task.continueWithTask(Task.java:369)
       at bolts.Task.then(Task.java:415)
       at bolts.Task.then(Task.java:407)
       at bolts.Task.run(Task.java:486)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)

通常在崩溃中我会找到一行

at com.justmedit.datatrix.MainActivity.done(MainActivity.java:90)

这让我找到了导致崩溃的线路。 有人可以就发生这种情况的原因或可能性给我建议,以便我可以调查此问题并在下一个版本中修复它。谢谢!

添加了我用于缩放位图的代码 -

public Bitmap ScaleImage( String value, float dimension){
        Bitmap bitmap = BitmapFactory.decodeFile(value);
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scale;
        if (width>height){scale=dimension/width;}
        else {scale=dimension/height;}
        ExifInterface exif;
        Matrix matrix = new Matrix();
        try {
            exif = new ExifInterface(value);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orientation);
            if (orientation == 6) {
                matrix.postRotate(90);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Log.d("EXIF", "Exif: " + orientation);}

        }catch (IOException e){e.printStackTrace();}
        matrix.postScale(scale, scale);
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,width, height, matrix, true);
        return resizedBitmap;
    }

这让我可以传递图像在 SD 卡上的位置和一个浮点数,该浮点数确定图像重新缩放后的最大尺寸。

您必须以样本大小创建位图。看看 Loading bitmaps efficiently.

 public static int calculateInSampleSize(

      BitmapFactory.Options options, int reqWidth, int reqHeight) {
       // Raw height and width of image
       final int height = options.outHeight;
       final int width = options.outWidth;
       int inSampleSize = 1;

       if (height > reqHeight || width > reqWidth) {
        if (width > height) {
         inSampleSize = Math.round((float) height
           / (float) reqHeight);
        } else {
         inSampleSize = Math.round((float) width / (float) reqWidth);
        }
       }

       return inSampleSize;
      }

以下方法将从 Byte 数组中以样本大小解码 Bitmap

public static Bitmap decodeSampledBitmapFromBytes(byte[] bytes, int reqWidth,
        int reqHeight) {

       Bitmap bm = null;
       // First decode with inJustDecodeBounds=true to check dimensions
       final BitmapFactory.Options options = new BitmapFactory.Options();
       options.inJustDecodeBounds = true;
       BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

       // Calculate inSampleSize
       options.inSampleSize = calculateInSampleSize(options, reqWidth,
         reqHeight);

       // Decode bitmap with inSampleSize set
       options.inJustDecodeBounds = false;
       bm =  BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);

       return bm;
      }

      public static int calculateInSampleSize(

      BitmapFactory.Options options, int reqWidth, int reqHeight) {
       // Raw height and width of image
       final int height = options.outHeight;
       final int width = options.outWidth;
       int inSampleSize = 1;

       if (height > reqHeight || width > reqWidth) {
        if (width > height) {
         inSampleSize = Math.round((float) height
           / (float) reqHeight);
        } else {
         inSampleSize = Math.round((float) width / (float) reqWidth);
        }
       }

       return inSampleSize;
      }

100是一个高度和宽度,你可以根据需要修改。

 Bitmap bitmap = decodeSampledBitmapFromBytes(bytes, 100, 100);

希望对您有所帮助!