【问题标题】:Android - AsyncTask fatal exceptionAndroid - AsyncTask 致命异常
【发布时间】:2013-07-25 15:07:03
【问题描述】:

我从 javaCameraView 加载位图中的图像。这是发送到异步任务以便将其发送到 php 文件。在第一秒没有问题。 在这段时间之后,我遇到了线程问题,但我没有找到解决方案。 这是 LogCat:

    07-25 16:36:29.492: E/AndroidRuntime(17507): FATAL EXCEPTION: AsyncTask #5
    07-25 16:36:29.492: E/AndroidRuntime(17507): java.lang.RuntimeException: An error occured while executing doInBackground()
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at   android.os.AsyncTask$3.done(AsyncTask.java:299)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.lang.Thread.run(Thread.java:856)
    07-25 16:36:29.492: E/AndroidRuntime(17507): Caused by: java.lang.OutOfMemoryError
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.lang.String.<init>(String.java:375)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.lang.String.<init>(String.java:238)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at android.util.Base64.encodeToString(Base64.java:456)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at com.example.objectDetect.SendData.getStringFromBitmap(SendData.java:186)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at com.example.objectDetect.SendData.doInBackground(SendData.java:63)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at com.example.objectDetect.SendData.doInBackground(SendData.java:1)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    07-25 16:36:29.492: E/AndroidRuntime(17507):    ... 5 more

我认为问题出在这个函数上,但我不知道为什么:

private String getStringFromBitmap(Bitmap bitmapPicture)
{
     if(!bitmapPicture.isRecycled())
     {
         final int COMPRESSION_QUALITY = 100;
         String encodedImage;
         ByteArrayOutputStream byteArrayBitmapStream = new ByteArrayOutputStream();
         bitmapPicture.compress(Bitmap.CompressFormat.PNG, COMPRESSION_QUALITY, byteArrayBitmapStream);
         byte[] b = byteArrayBitmapStream.toByteArray();
         encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
         return encodedImage;
     }
     else
     {
         return null;
     }
}

经过大量测试,我有一个不同的 logcat,但它总是内存问题。我在运行函数的线程中创建了一个位图。

下面是logcat:

    07-26 09:42:50.491: E/AndroidRuntime(31291): FATAL EXCEPTION: Thread-27487
    07-26 09:42:50.491: E/AndroidRuntime(31291): java.lang.OutOfMemoryError
    07-26 09:42:50.491: E/AndroidRuntime(31291):    at android.graphics.Bitmap.nativeCreate(Native Method)
    07-26 09:42:50.491: E/AndroidRuntime(31291):    at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
    07-26 09:42:50.491: E/AndroidRuntime(31291):    at android.graphics.Bitmap.createBitmap(Bitmap.java:620)
    07-26 09:42:50.491: E/AndroidRuntime(31291):    at com.example.objectDetection.objectDetectionView$1.run(objectDetectionView.java:197)

提前感谢您的帮助。

【问题讨论】:

  • 或许是的,但是这个问题会在大约 1 到 2 分钟的测试中出现...
  • base-64 编码真的有必要吗?处理二进制数据会更有效率......正是这个操作消耗了太多内存
  • 是的,因为我将它发送到 php 以便在服务器上进行比较。
  • 你有一张大照片的位图,然后创建一个 byte[] 数组来保存 PNG 编码的二进制数据,然后创建这个 PNG 数据的大型 base-64 字符串表示。你的内存用完了。将二进制数据发送到您的服务器,如有必要,对其进行 base-64 编码

标签: android multithreading exception android-asynctask


【解决方案1】:

下面的代码是我为了避免加载位图时出现内存不足错误而设计的。

   private Bitmap loadImageFromNetwork(String urlToUse) {
    Bitmap img = null;
    URL url;
    try {
       //A uniform resource locator aka the place where the data is       
       //located
       url = new URL(urlToUse);
       //Opens an HTTPUrlConnection and downloads the input stream into a
       //Bitmap
       final BitmapFactory.Options options = new BitmapFactory.Options();
       // Prevents loading of image into memory and just ascertains bounds and memory footprint
       options.inJustDecodeBounds = true;

       BitmapFactory.decodeStream(url.openStream(),null,options); // gather image data
       options.inSampleSize = Photo.calculateInSampleSize(options, 
               Photo.THUMBNAIL_WIDTH, Photo.THUMBNAIL_HEIGHT);
       options.inJustDecodeBounds = false;
       img = BitmapFactory.decodeStream(url.openStream(),null,options);

    } catch (MalformedURLException e) {
       Log.i("PAR", "URL is malformed");
       e.printStackTrace();
    } catch (IOException e) {
       Log.i("PAR", "Failed to decode Bitmap");
       e.printStackTrace();
    }

    return img;

} // end load function


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);
        } // end if
    } // end out if
    return inSampleSize;
}

这里要确定的关键是初始加载不包括整个图像。 inJustDecodeBounds 标志设置为 true,这与听起来完全一样。它只解码边界,因此您可以提前确定图像是否太大。我的建议是确定边界和其他相关数据,然后在加载所有图像之前进行调整。在本例中,我将大图像转换为缩略图。

使用此技术应在压缩图像之前减小图像大小。我想权衡是您正在减少加载图像,这可能意味着质量较低。但是,如果您的内存不足,如果您愿意稍微缩小图像,这可能是一个可行的选择。

【讨论】:

  • 问题是位图是从 javacamera 视图加载的。所以我加载了一个矩阵。
  • 您可能应该在问题中包含有关您的问题的更多信息。提供的内容很难提供一个好的答案。
  • 我从 javaCameraView 加载位图中的图像。这是发送到异步任务以便将其发送到 php 文件。
  • 您应该在问题中包含更详细的信息,以便每个人都有正确的上下文来帮助您。对原始问题进行编辑
猜你喜欢
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 2015-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多