我试图将我的SD卡中的图像发送到php服务器... 我创建了2个类:第一个是MainActivity.java,第二个是Base64.java,它以Base64格式编码。具有Base64格式的字符。
我的MainActivity.java是:
public class MainActivity extends Activity {
InputStream inputStream;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/DCIM/Camera/1378889572299.jpg");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream); //compress to which format you want.
byte [] byte_arr = stream.toByteArray();
String image_str = Base64.encodeBytes(byte_arr);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image",image_str));
Log.e("ok", "1");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://myserver.com/upload_image.php");
Log.e("ok", "3");
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
Log.e("ok", "4");
HttpResponse response = httpclient.execute(httppost);
Log.e("ok", "5");
String the_string_response = convertResponseToString(response);
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException{
String res = "";
StringBuffer buffer = new StringBuffer();
inputStream = response.getEntity().getContent();
final int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
}
});
if (contentLength < 0){
}
else{
byte[] data = new byte[512];
int len = 0;
try
{
while (-1 != (len = inputStream.read(data)) )
{
buffer.append(new String(data, 0, len)); //converting to string and appending to stringbuffer…..
}
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
inputStream.close(); // closing the stream…..
}
catch (IOException e)
{
e.printStackTrace();
}
res = buffer.toString(); // converting stringbuffer to string…..
final String res2 = res;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Result : " + res2, Toast.LENGTH_LONG).show();
}
});
//System.out.println("Response => " + EntityUtils.toString(response.getEntity()));
}
return res;
}
}
我有这个错误:
........OutOfMemoryError
….at java.lang.AbstractStringBuilder.(AbstractStringBuilder.java:81)
….at java.lang.StringBuilder.(StringBuilder.java:68)
….at java.net.URLEncoder.encode(URLEncoder.java:98)
….at org.apache.http.client.utils.URLEncodedUtils.encode(URLEncodedUtils.java:184)
….at org.apache.http.client.utils.URLEncodedUtils.format(URLEncodedUtils.java:163)
….at org.apache.http.client.entity.UrlEncodedFormEntity.(UrlEncodedFormEntity.java:71)
….at com.example.imageuploadonserver.MainActivity.onCreate(MainActivity.java:43)
第43行是: httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
我在代码中做了一些更改......我将sdcard中的图像源替换为drawabel.ic_luncher:
Bitmap bitmap = BitmapFactory.decodeFile(“/sdcard/DCIM/Camera/1378889572299.jpg”);
由此:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
它的工作succseffuly !!!!
我搜索了很多,但要么我使用了错误的关键字,要么互联网上没有简单的解决方案。我希望有人可以帮助我。
最好的问候和提前感谢,Fadel。
答案 0 :(得分:3)
假设您的图像大约是5Mo,因为它是您相机的照片。
当你不再需要它时,你应该尝试释放内存:
这样做会释放大约9到14个月
但是在所有情况下,通过对其进行编码(base64Encode或UrlEncode),您的堆大小将增加两倍于位图大小。 Abetter方式应该是将文件的内容写入HTTP流,将从文件中读取。
答案 1 :(得分:2)
似乎您要上传的图片尺寸非常大。您需要在创建位图时缩小它。 ic_launcher png的分辨率非常低,因此在创建位图时不会造成任何麻烦。
检查此链接是否有效加载位图 - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
希望它有所帮助.. :)
答案 2 :(得分:0)
为避免一次将所有数据加载到内存中,我会使用ChunkedOutputStream 以块的形式传输数据。如果您对此非常小心,您可以上传无限大小的图像,因为它永远不需要将整个内容放在内存中。
答案 3 :(得分:0)
处理客户&lt; - &gt;时Server WebServices,将整个请求或响应数据加载到String或任何内存对象中是不好的做法,应该尽可能避免。在许多情况下都可以避免。
为什么要避免?
因为在许多情况下,您无法保证数据的大小,并且通常会导致您出现OOM异常。
你应该怎么做?
对于大多数请求数据,您可以在发送它时构建它(XML,JSON,Whatever-serialization),并且您不需要在内存中重新构建整个结构以便能够对其进行序列化。
对于大多数答案数据,您可以解析流中的对象并将其保存在数据库中,或者丢弃您不需要的流的任何部分。不将整个响应加载为String。
在您的具体情况中,您有一个磁盘上的文件,它是您要压缩的图像。使用标准库或任何其他图像库将其转换为90%JPEG到另一个文件。然后,您可以将文件直接流式传输到httpPost.entity的输出流。
甚至可能有些库(甚至可能是标准库?)为您提供了直接从第一个图像文件获取带有压缩图像的InputStream的可能性。
在这两种情况下,将第一个InputStream封装在另一个执行Base64转换的InputStream中,然后就在那里。
这样,对于流缓冲区,您永远不需要一次加载超过几千字节的内存。