【问题标题】:MemoryOutOfBounds exception occuring while passing the base 64 string to SOAP将 base64 字符串传递给 SOAP 时发生内存超出范围异常
【发布时间】:2013-03-16 01:21:25
【问题描述】:

我的应用程序在 Sony Experia (2.3) 上成功运行,但在三星 Galaxy Tab (4.1) 上运行时出现异常。我的问题是,在录制视频并将其转换为 base64 字符串后,将其解析为肥皂时出现错误。

这是我捕获视频的代码(传递意图):

Intent videoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

videoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);

videoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);

startActivityForResult(videoIntent, ACTION_TAKE_VIDEO);

关于Activity结果方法:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if ((requestCode == ACTION_TAKE_VIDEO && resultCode == RESULT_OK)) {
System.out.println("capturing video");
Uri selectedImage = data.getData();
String videoPath = getRealPathFromURI(selectedImage);

Bitmap bm = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Images.Thumbnails.MINI_KIND);
videoview.setImageBitmap(bm);
System.out.println("videobitmap=="+bm);

bytes[]datas = null;
String dataPath = videoPath;
InputStream is = null;

try {
is = new FileInputStream(dataPath);
datas = readBytes(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

String encodedImage = Base64.encodeToString(datas, Base64.DEFAULT);
isInternetPresent = cd.isConnectingToInternet();

if (isInternetPresent) {
new BufferingVideo().execute(encodedImage);
} else {
Toast.makeText(getApplicationContext(), "Sorry, we couldn't connect to server, please check your 
internet connection", Toast.LENGTH_LONG).show();
}
}
}

public byte[] readBytes(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;

while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}

return byteBuffer.toByteArray();
}

public String getRealPathFromURI(Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}

现在将 base64 字符串传递给 Webservice:

protected String doInBackground(String... params) {
String st = params[0];
System.out.println("st==== " + st);

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME4);

System.err.println("Request  = " + request);
request.addProperty("VideoBuffer", st);
request.addProperty("VideoName", "VideoCar");
request.addProperty("ModuleName", modulename);
}

我的 Logcat 错误是:

致命异常:AsyncTask #5 java.lang.RuntimeException:执行 doInBackground() 时发生错误 在 android.os.AsyncTask$3.done(AsyncTask.java:299) 在 java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 在 java.util.concurrent.FutureTask.setException(FutureTask.java:124) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 在 java.util.concurrent.FutureTask.run(FutureTask.java:137) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 在 java.lang.Thread.run(Thread.java:856) 引起:java.lang.OutOfMemoryError 在 java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94) 在 java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145) 在 java.lang.StringBuffer.append(StringBuffer.java:219) 在 org.ksoap2.serialization.SoapObject.toString(SoapObject.java:456) 在 java.lang.StringBuilder.append(StringBuilder.java:202) 在 web.org.HouseRentInsertAds$BufferingVideo.doInBackground(HouseRentInsertAds.java:897) 在 web.org.HouseRentInsertAds$BufferingVideo.doInBackground(HouseRentInsertAds.java:1) 在 android.os.AsyncTask$2.call(AsyncTask.java:287) 在 java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

请给我一个解决方案。

【问题讨论】:

标签: android out-of-memory


【解决方案1】:

您必须压缩图像才能将整个图像发送到服务器。

公开

String String_Image; 
Bitmap bitmap;

这里是解码图像并将压缩后的图像发送到服务器的过程

File image_file = new File(path);
decodeFile(image_file);         
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bao);
byte[] ba = bao.toByteArray();
String_Image = Base64.encodeBytes(ba);

decodeFile() 函数将解码您的文件。

private Bitmap decodeFile(File f)
    {
        try
        {
            // Decodes image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size to scale to
            final int REQUIRED_SIZE = 70;

            // Finds the correct scale value which should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE
                    && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;

            // Decodes with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            bitmap = BitmapFactory.decodeStream(new FileInputStream(f), null,
                    o2);
            return bitmap;
        } catch (FileNotFoundException e)
        {
        }
        return null;
    }

发送String_Image 到服务器。

此代码适用于图像,但您也可以为其他代码执行相同的方式。尝试一些更改。

希望它会起作用。

【讨论】:

  • 在低版本中无法处理太多内存来执行任务。你应用我的概念了吗?
  • 是的,我已经申请了...但是 decodeStream 不起作用,它给出了显示 null 的错误。我正在使用 API level8(google API)。
  • 你能清楚地指定某种方式吗......我的问题是 ecplise 是否占用了太多空间来分配位图?如果那么是否有一个恒定的像素大小可以在包括平板电脑在内的所有设备中接受(有效) .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 2014-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多