I'm retrieve the String of image name and having to download bitmap from server
For getting String of image name fron JSON data and download using this link :
String str_ImgURL_bmp_pattern = "http://xxxx/xxx/MobileService.svc/DownloadFile/FileName/" + imageName;
download_PngFile(str_ImgURL_bmp_pattern);
void download_PngFile(String fileUrl) {
Log.e("In download_PngFile ", " str_imgList_imageaudioPath = " + imageName);
Bitmap imagenObtenida = null;
try {
URL ImgUrl = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection) ImgUrl.openConnection();
conn.connect();
imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
//Log.e("imagenObtenida", " = " + imagenObtenida);
String fotoname = imageName;
File file = new File(newFolder, fotoname);
int sizeOfImage = (int) file.length();
Log.e("sizeOfImage ", " = " + sizeOfImage + "# " + imageName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imagenObtenida.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
// Log.e("Png = ", "DownLoad complete");
} catch (Exception e) {
}
} catch (IOException e) {
e.printStackTrace();
}
}
But this some images are download and after sometime app crashes and I get the error in the title in logcat.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:549)
at com.example.tazeen.classnkk.AllPosts_Page.download_PngFile(AllPosts_Page.java:896)
at com.example.tazeen.classnkk.AllPosts_Page.getDoenLoaddata(AllPosts_Page.java:820)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:781)
at com.example.tazeen.classnkk.AllPosts_Page$GetgetAllImagePath_List.doInBackground(AllPosts_Page.java:771)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
The error at this line :imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream());
How to resolve this issues.
So basically the exception is pretty clear.
You are out of memory.
There are some possible solutions:
1. Scale down your images:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap imagenObtenida = BitmapFactory.decodeStream(conn.getInputStream(), null, options);
This is required, if even a single image download causes a crash.
2. Don't decode at the same time
So don't use a ThreadPoolExecutor
3. Combinations
For example:
-just use 2 parallel Threads
-check the available memory and set a thread number which fits to the current memory
-catch out of memory exceptions and wait till other thread finish
Related
I am making a http call to an api for a string response.
The result contains intentional % signs in a sentence like:
"This land is 95% fertail and 5% contaminated"
Android throws IllegalArgumentException: Invalid % sequence at 1756 which corresponds to the "95%" part.
EDIT: StackTrace:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
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:818)
Caused by: java.lang.IllegalArgumentException: Invalid % sequence at 1756: [{"address":{"addressComponen...
My httpGet method:
public String makeHttpGetRequestUtf8(String urlStr) throws IOException {
String result = "";
try {
URL url = new URL(urlStr);
BufferedReader brIn = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
String line = "";
while ((line = brIn.readLine()) != null)
result += line;
}catch (Exception e){
Log.e("HTT_GET", "Failed to make httpGetRequestUtf8: " + e);
}
String afterDecode = URLDecoder.decode(result, "UTF-8");
return afterDecode;
}
Android throws IllegalArgumentException: Invalid % sequence at 1756 which corresponds to the "95%" part.
Server writes this data with this metod and so I believe the encoding should be fine?
File file = new File(path/filename.txt);
String content = writeMeToFile;
Writer out;
try{
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), "UTF8"));
if(!file.exists()){
file.createNewFile();
}else{
FileUtils.copyFile(file, dest);
out.write(content);
out.close();
}
} catch (IOException e) {
Logger.getLogger(UpdateAds.class.getName()).log(Level.SEVERE, null, e);
}
Side question/note: Somehow characters like 'ä', 'ö', 'ü', 'õ' are fine in the browser but show up as � in android.
I don't understand at which side am I encoding the string wrong. Since the text is fine in the browser I am thinking it's android, but the httpGet method is done by the book.
Thanks!
I want to upload an image to server but i need to send 2 more things in order to connect with the server any HELP cause im really stuck on this one.
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// MultipartEntity entity = new MultipartEntity();
try {
File file = new File(path);
// Adding file data to http body
builder.addPart("image", new FileBody(file));
// Extra parameters if you want to pass to server
builder.addTextBody("confid", name);
builder.addTextBody("udid", id);
entity = builder.build();
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
Here are the errors from android Studio logcat
0-08 12:06:01.216 8616-8787/? E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NoClassDefFoundError: org.apache.http.entity.mime.MultipartEntityBuilder
at com.example.oleg.myapplication.MainActivity$1.uploadFile(MainActivity.java:305)
at com.example.oleg.myapplication.MainActivity$1.doInBackground(MainActivity.java:285) at com.example.oleg.myapplication.MainActivity$1.doInBackground(MainActivity.java:279) at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
I am using the below code to fetch xml file from the server and due to heavy and large xml file, it got crashed and showing Out of memory Issue.
public class Connect {
static BufferedReader in=null;
String result=null;
Context context;
//Establish connection with web server
public String HTTPConnect(String uri1,List<NameValuePair> list,Context context)
{
this.context=context;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(uri1);
if(list!=null)
{
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(list);
httpPost.setEntity(formEntity);
}
HttpResponse httpResponse = httpClient.execute(httpPost);
in = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
long heapSize = Runtime.getRuntime().totalMemory();
if(in!=null)
{
while ((line = in.readLine()) != null) {//crasheg here
sb.append(line + NL);
}
in.close();
}
result = sb.toString();
}
catch(UnsupportedEncodingException e)
{
String err = (e.getMessage()==null)?"Cant connect to server":e.getMessage();
ShowDialog();
}
catch (MalformedURLException e) {
String err = (e.getMessage()==null)?"Malformed Exception":e.getMessage();
ShowDialog();
}
catch(Exception ex)
{
String err = (ex.getMessage()==null)?"NetworkConnectionException":ex.getMessage();
ShowDialog();
}
finally {
if (in != null) {
try {
in.close();
} catch (Exception ex) {
String err = (ex.getMessage()==null)?"Excepion":ex.getMessage();
ex.printStackTrace();
}
}
}
return result;
}
I know that that I am copying the whole XML in String and due to heavy file, It gor crashing. It is working fine in small size of XML file, but what are the alternative for large xml file. I am uing SAX parser for parsing this xml file.
[EDIT]
Below is the logcat:
FATAL EXCEPTION: AsyncTask #4
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1096)
Caused by: java.lang.OutOfMemoryError
java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)
java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:136)
java.lang.StringBuilder.append(StringBuilder.java:272)
java.io.BufferedReader.readLine(BufferedReader.java:452)
com.kxs.appitize.Connect.HTTPConnect(Connect.java:56)
com.kxs.appitize.ListRestaurants$Asyn_rest.doInBackground(ListRestaurants.java:168)
com.kxs.appitize.ListRestaurants$Asyn_rest.doInBackground(ListRestaurants.java:1)
01-at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
Activity com.kxs.appitize.TabsMainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#44f4fb28 that was originally added here
android.view.WindowLeaked: Activity com.kxs.appitize.TabsMainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#44f4fb28 that was originally added here
at android.view.ViewRoot.<init>(ViewRoot.java:247)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at com.kxs.appitize.ListRestaurants$Asyn_rest.onPreExecute(ListRestaurants.java:156)
at android.os.AsyncTask.execute(AsyncTask.java:391)
at com.kxs.appitize.ListRestaurants.onCreate(ListRestaurants.java:133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
at android.app.ActivityThread.startActivityNow(ActivityThread.java:2503)
at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339)
at com.kxs.appitize.TabGroupActivity.startChildActivity(TabGroupActivity.java:72)
at com.kxs.appitize.ListCategories$1.onClick(ListCategories.java:109)
at android.view.View.performClick(View.java:2408)
at android.view.View$PerformClick.run(View.java:8816)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
copying the whole XML in String and due to heavy file
Bad idea. First you need to cache the xml in a temporary directory. It should never be in the RAM.
Once you do that use SAX to parse the file. During parsing try not to keep the whole structure in the RAM, instead parse in bite sized chunks.
Try to use inputStream to parse XML. The inputStrem does not increase Android stack size and it's prevent possibles OOM with large String. I have the same things with large JSON and now, i use Jackson to parse JSON directly from Stream.
You can find equivalent library for parsing XML.
I am reading the youtube response in Stream and converting it to String. using the below code:
URL: http://gdata.youtube.com/feeds/api/users/cnn/uploads?&v=2&max-results=25&alt=json
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
This code is working in fine in all devices except Android 4.0 devices. I am getting the below logcat:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at com.android.mypack.MyApplications.convertStreamToString(MyApplications.java:959)
at com.android.mypack.MyApplications.access$61(MyApplications.java:951)
at com.android.mypack.MyApplications$YoutubeTask.doInBackground(MyApplications.java:2303)
at com.android.mypack.MyApplications$YoutubeTask.doInBackground(MyApplications.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at com.android.mypack.MyApplications.convertStreamToString(MyApplications.java:959)
at com.android.mypack.MyApplications.access$61(MyApplications.java:951)
at com.android.mypack.MyApplications$YoutubeTask.doInBackground(MyApplications.java:2303)
at com.android.mypack.MyApplications$YoutubeTask.doInBackground(MyApplications.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Please help me to overcome this error.
Thanks in Advance.
Well, OutOfMemoryErrors are coming obviously when the virtual machine runs out of memory. The important point here is that the exact stack trace might not be informative, because it could happen that another thread uses all of the memory. Or something memory-consuming happened on this thread before this code, and this code was only the "last straw". This URL certainly does not contain too many bytes, I think the problem is in another place.
You could try a memory analyzer:
Android ==> Memory Analysing ==> Eclipse memory analyzer?
I get a very common crash below from the code below.
I thought my try, catches will have handled that.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1102)
Caused by: java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:65)
at java.io.InputStreamReader.<init>(InputStreamReader.java:65)
at com.test.test.FinderMain.grabPlaneRoute(FinderMain.java:759)
at com.test.test.FinderMain.access$7(FinderMain.java:729)
at com.test.test.FinderMain$GetRouteTask.doInBackground(FinderMain.java:684)
at com.test.test.FinderMain$GetRouteTask.doInBackground(FinderMain.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
Line 759 is within grabPlaneRoute and is the line containing the "StringBuilder total = new StringBuilder();"
Can someone help with this, it is driving me crazy! :-)
private void grabPlaneRoute(String adshex) {
List<GeoPoint> localList = new ArrayList<GeoPoint>();
HttpURLConnection con = null;
URL url;
InputStream is=null;
try {
url = new URL("http://www.testurl.com&test=" + adshex);
con = (HttpURLConnection) url.openConnection();
con.setReadTimeout(20000 /* milliseconds */);
con.setConnectTimeout(60000 /* milliseconds */);
con.setRequestMethod("GET");
con.setDoInput(true);
// Start the query
con.connect();
is = con.getInputStream();
}catch (IOException e) {
//handle the exception !
e.printStackTrace();
return;
}
//localList = decodePoly(convertStreamToString(is));
//Log.i("HTTP DUMP", convertStreamToString(is));
BufferedReader r = new BufferedReader(new InputStreamReader(is),8024);
StringBuilder total = new StringBuilder();
String line;
try {
while ((line = r.readLine()) != null) {
String[] separated = line.split(",");
GeoPoint p = getPoint(Double.valueOf(separated[0]),Double.valueOf(separated[1]));
localList.add(p);
}
}catch (IOException e) {
//handle the exception !
e.printStackTrace();
}
drawPlaneRoute(localList);
}
Line 759 is actually the line that begins with BufferedReader r = new ....
The variable is is null.
What happens when con.GetInputStream returns a null, and doesn't throw an exception? You're not handling that case, and that's likely what's happening here.
In addition, I don't see a need for the either try/catch block at all. Just let the exception percolate up the call stack. You're hiding the IOException now, preventing anyone calling grabPlaneRoute from discovering that an error occurred.
It's fairly impossible for StringBuilder total = new StringBuilder(); to cause a NullPointerException. On the other hand, the nearest cause of the Exception is in the logtrace:
at java.io.Reader.<init>(Reader.java:65)
at java.io.InputStreamReader.<init>(InputStreamReader.java:65)
Which makes me think that it's caused by:
BufferedReader r = new BufferedReader(new InputStreamReader(is),8024);
In that case, the only thing that could be null is is.