I have written an Android application which downloads pdf files through web service. I am using kSoap2 android library to parse the response of web service which basically contains file name & file data.
I have written following code. Please review & tell how to increase the speed I think there is some small defect in code which reduces the speed. I am using version 2.5.1 of kSoap2.
public void downloadPdfFiles(File fileDocsDir, int noOfFiles)
throws NullPointerException, SoapFault, XmlPullParserException,
FileNotFoundException, IOException, Exception {
System.gc();
// Download files from web service and save them in the folder.
soapObject = new SoapObject(NAMESPACE, METHOD_NAME);
soapObject.addProperty("startingFile", noOfFiles);
soapObject.addProperty("deviceId", deviceId);
soapObject.addProperty("loginId", loginId);
soapObject.addProperty("byoinId", "1");
envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(soapObject);
// Calling the web service
System.gc();
androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
// Getting Response through xml mainly generated as soap:reponse.
responseBean = (SoapObject) envelope.getResponse();
// Array of PDFInfoBean.
list = (SoapObject) responseBean.getProperty(0);
FileOutputStream outputStream = null;
BufferedOutputStream bufferedOutputStream = null;
// Get Individual PDF Details from Array.
SoapObject pdfDetails = null;
mIncrement = noOfFiles;
// Log.i("Increment Values", String.valueOf(mIncrement));
File pdfFile = null;
for (int i = 0; i < list.getPropertyCount(); i++) {
pdfDetails = (SoapObject) list.getProperty(i);
// Get PDF File Name.
pdfDocName = pdfDetails.getProperty(1).toString();
Log.i(TAG, "File Name: " + pdfDocName);
// Check for last file.
if (pdfDocName.equalsIgnoreCase("EOF")) {
mFlag = false;
break;
}
// Creating PDF File.
pdfFile = new File(fileDocsDir, pdfDocName);
// Writing PDF file received through web service.
if (pdfFile.exists()) {
Log.i(TAG, pdfFile.getName() + " File Already Exists");
} else {
outputStream = new FileOutputStream(pdfFile);
bufferedOutputStream = new BufferedOutputStream(outputStream);
bufferedOutputStream.write(Base64Coder.decode(pdfDetails
.getProperty(0).toString()));
mIncrement = mIncrement + 1;
bufferedOutputStream.close();
outputStream.close();
bufferedOutputStream = null;
outputStream = null;
}
pdfDetails = null;
pdfDocName = null;
pdfFile = null;
System.gc();
}
soapObject = null;
envelope = null;
responseBean = null;
list = null;
androidHttpTransport = null;
System.gc();
}
-
2\$\begingroup\$ what are the sizes of these pdf's? you're buffering the entire things in memory before writing them out; I suspect even without your System.gc's to spice things up, you observe lots of gc activity and possibly OOME's. \$\endgroup\$Ron– Ron2011年03月14日 07:12:54 +00:00Commented Mar 14, 2011 at 7:12
-
\$\begingroup\$ Basically the size of pdf's that are to be received at client side are of 1 mb from 533mb folder at server side. \$\endgroup\$Shashank_Itmaster– Shashank_Itmaster2011年03月14日 07:34:53 +00:00Commented Mar 14, 2011 at 7:34
-
\$\begingroup\$ can you post server side web service code also. Thanks Sampath \$\endgroup\$user11721– user117212012年03月10日 02:04:35 +00:00Commented Mar 10, 2012 at 2:04
2 Answers 2
Forcing
System.gc()
isn't a good practice.outputStream = new FileOutputStream(pdfFile); bufferedOutputStream = new BufferedOutputStream(outputStream);
should be wrapped into 1 variable to do a single
close()
afterwards:outputStream = new BufferedOutputStream(new FileOutputStream(pdfFile));
All operations with
outputStream
should be put intry-finally
block:outputStream = new ... try { outputStream.write(...); ... } finally { outputStream.close(); }
Agree with the first comment: your file may simply not fit in memory. In SOAP API there should be some mean of getting the
InputStream
instead of an in-memory string.
Sorry for the formatting, couldn't fight the editor.
Good luck!
-
\$\begingroup\$ Thanks for your answer.I already overcome the problem of OutOfMemory issue,here I posted it for just get better review from sharp programmers. \$\endgroup\$Shashank_Itmaster– Shashank_Itmaster2011年03月25日 10:07:25 +00:00Commented Mar 25, 2011 at 10:07
-
1\$\begingroup\$ I agree with 3., but it should be mentioned that if Java 7 is available, ARM-blocks can deal with that pain. \$\endgroup\$Landei– Landei2012年03月10日 19:15:07 +00:00Commented Mar 10, 2012 at 19:15
-
\$\begingroup\$ @Landei also known as try-with-resources. \$\endgroup\$Adam– Adam2012年10月26日 23:24:09 +00:00Commented Oct 26, 2012 at 23:24
@weekens noted:
Forcing System.gc() isn't a good practice.
This is so true. In fact, calling System.gc()
is likely to have a major impact on the performance of your application.