OutOfMemory error in Android XML Pull parser - android

I parse an XML document from a HTTPResponse.
Previously I initiated the parser with a String object created from the InputStream.
When I changed the setup so the inputStream isused directly in the parser I get OutOfMemory Exceptions.
The strange thing is that parsing the String worked without problems before, so I wonder why the InputStream should need more memory.
Previous code:
final byte[] encodedResponseBytes = IOUtils.toByteArray(httpResponse
.getEntity().getContent());
String message = new String(encodedResponseBytes);
parser.setInput(new StringReader(message));
New code:
InputStream stream = httpResponse
.getEntity().getContent();
parser.setInput(stream, null);

By changing the code I don't have a problem anymore:
InputStream stream = request.getResponseStream();
reader = new InputStreamReader(stream);
this.xmlParser.setInput(reader);

Related

BitmapFactory.decodeStream not working

I'm having a bit of a problem with decodeStream returning null. It seems to be a fairly common problem around, but it's usually pinned down to one of two problems:
An OutOfMemory exception thrown by attempting to load a large bitmap in it's entirety.
Attempting to use the same input stream twice.
However, I'm not doing either. The code to run it is simply
stream = new java.net.URL(url).openStream();
Bitmap image = BitmapFactory.decodeStream(stream);
stream.close();
with the URL set to here. image is null after this code is complete. This issue's been driving me completely insane - it works fine on PNGs but seems to fall apart under every BMP I can give it, so any help would be appreciated.
Ultimately, the answer was found here, using an InputStream returned by a BufferedHTTPEntity. While it seems needlessly complex, I can only assume that simply getting a stream from the URL object directly doesn't return a stream of the appropriate type, and so it wasn't reading out all the data properly.
Cross-posting the code in case the question is erased:
private static InputStream fetch(String address) throws MalformedURLException,IOException {
HttpGet httpRequest = new HttpGet(URI.create(address) );
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();
return instream;
}

File sent using HttpPost corrupted and/or truncated

I receive a file using the following code:
byte[] fileBytes;
....
JSONObject postJSON = new JSONObject();
postJSON.put("file_name", filename);
postJSON.put("client_id", clientID);
HttpPost post = new HttpPost(fileURL);
StringEntity se = new StringEntity( postJSON.toString(), "UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = httpClient.execute(post);
fileBytes = EntityUtils.toByteArray(response.getEntity());
Using the debugger, I see that the response gets an entity 27136 bytes in length, which is the correct length of the test file, but the fileBytes array is only 11470 bytes long. Can anyone tell my why this truncation is taking place? When I try to get other files, a similar truncation takes place, so it is not a function of the specific file or a specific file length.
Using the following code, I get 11997 bytes for the same file:
StringBuilder stringBuilder = new StringBuilder("");
stringBuilder.append(EntityUtils.toString(response.getEntity()));
fileBytes = stringBuilder.toString().getBytes();
Reading from an InputStream, I get 12288 bytes:
fileBytes = new byte[1024];
InputStream inputStream = response.getEntity().getContent();
int bytesRead = 0;
while(true){
bytesRead = inputStream.read(fileBytes);
if (bytesRead <= 0)
break;
....
}
Changing the encoding to UTF-16 gets me an internal server error.
I also tried the following:
InputStream inputStream = response.getEntity().getContent();
response.getEntity().getContentLength()];
while ((getByte = inputStream.read()) != -1) {
bos.write(getByte);
}
bos.close();
This also gave me a file of 11470.
In all cases, the files are corrupted, and cannot be opened. When compared in a binary file viewer, the firs 11 bytes match, and then the files diverge. I could not find any pattern in the corrupted file.
OK, the answer is apparently that all of the above are fine. The problem was with the server, which was not configuring the data stream correctly: Content-type was text/plain for all files, rather than application/pdf, and so on as appropriate.
My first clue was when we put a text file on the server, and it came over successfully. At that point I started working with the server side, and we figured it out pretty quickly.
Bottom line, if you are working on a server/client application, the problem might not be on your side.
I should have mentioned various posts which helped my construct the various versions that I collected above:
including this
and this
My apologies to various other helpful people whose posts I also looked at and up-voted.

Android - HTTP GET Request huge size of JSON response

I have a big JSON input (download the file) API and I don´t know how to parse this data. I need:
Save this data (entire JSON input) to text file or database. What is the best way for this?
Load this data from text file or database and create JSONArray from JSON tag "list" (first tag)
The solution should be fast and support Android 2.3. What you have recomend for this? Any ideas?
My code:
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(urls[0]);
HttpResponse httpResponse;
httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
... and what next ?...
FYI:
EntityUtils throws OutOfMemoryException
EDIT:
I try to save data to file like this:
InputStream inputStream = httpEntity.getContent();
FileOutputStream output = new FileOutputStream(Globals.fileNews);
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
And it´s OK. I load data:
FileInputStream fis = null;
StringBuffer fileContent = new StringBuffer("");
fis = new FileInputStream(Globals.fileNews);
byte[] buffer = new byte[1024];
while (fis.read(buffer) != -1) {
fileContent.append(new String(buffer));
}
But how convert StringBuffer to JSONObject? fileContent.ToString() is not ideal, sometimes I get OutOfMemoryException.
First of all: Dispose the HttpClient. Google discourages it:
Unfortunately, Apache HTTP Client does not, which is one of the many
reasons we discourage its use.
Source: developer.android.com
A good replacement is Google Volley. You have to build the JAR yourself but it just works like charm. I use for my setups Google Volley with OkHttp-Stack and GSON requests.
In your case you would write another Request which just writes the response out to the SD-card chunk by chunk. You don't buffer the string before! And some logic to open an input-stream from the file you wrote and give it to your JSON Deserializer. Jackson and GSON are able to handle streams out of the box.
Of course everything works with Android 2.3.
Don't, I repeat, don't try to dump the whole serialized stuff into a string or something. That's almost a OutOfMemoryException guarantee.

reading encoded string HTTP request to android

I have a RESTful WCF service that I am using to retrieve encoded photos and display them in android (trying to anyway). The problem I am having is that the InputStream or possibly something else stops reading the characters before the end.
The response is just an XML string, I intend to parse it myself so no need to worry about that. What I need to know is what in the following code is stopping the input stream from reading characters into my buffer.
HttpEntity responseEntity = response.getEntity();
char[] buffer = new char[(int)responseEntity.getContentLength()];
InputStream stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
reader.read(buffer);
stream.close();
Have you implemented the HttpURLConnection class.. this would cause this behavior.
http://developer.android.com/reference/java/net/HttpURLConnection.html

Convert a String or a InputStreamReader into InputSource

I just read some tutorials in order to parse a xml feed from the web and turn them into a Listview:
URL file = new URL("http://..../file.xml");
SAXParserFactory fabrique = SAXParserFactory.newInstance();
SAXParser parseur = fabrique.newSAXParser();
XMLReader xr = parseur.getXMLReader();
ReglageParseur gestionnaire = new ReglageParseur();
xr.setContentHandler(gestionnaire);
xr.parse(new InputSource(file.openStream()));
Everything is fine and I am able to parse xml.
My second step is to store the xml file from web into a xml file on the phone and only update it when user ask it. ( In fact, this xml file should not change or maybe once every 6 month, so I don't want to download it each time.)
So, what I did is to store the file on the phone and update it on user demand.
And I can read it by doing:
fIn = openFileInput("fichier.xml");
InputStreamReader isr = new InputStreamReader(fIn);
char[] inputBuffer = new char[255];
isr.read(inputBuffer);
String readString = new String(inputBuffer);
So, for now, everything seem fine and I am nearly happy.
The problem is now when I want to parse the new file on the phone:
xr.parse(InputSource);
I need an InputSource as parameter.
So my question is:
How can I turn my file in the phone into a InputSource?
I succeed to have a InputStreamReader or a String but would like to convert that into InputSource.
Thank a lot for any precious help
Well, I don't know what constructors are available on the Android version, but the J2SE InputSource class has a constructor with a Reader parameter. Have you tried that?
Alternatively, why not just construct an InputSource directly from the InputStream? I assume fIn is a FileInputStream? Why not just call:
InputSource input = new InputSource(fIn);
?
the best suitable line for me to convert string to InputSource is :
String myStringObject = "Hello this is string object to convert in InputSource";
InputSource inSource = new InputSource(new StringReader(myStringObject));

Categories

Resources