7
\$\begingroup\$

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();
    }
\$\endgroup\$
  • 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 Mar 14 '11 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 Mar 14 '11 at 7:34
  • \$\begingroup\$ can you post server side web service code also. Thanks Sampath \$\endgroup\$ – user11721 Mar 10 '12 at 2:04
5
\$\begingroup\$
  1. Forcing System.gc() isn't a good practice.

  2. 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));
    
  3. All operations with outputStream should be put in try-finally block:

    outputStream = new ...
    try {
        outputStream.write(...);
        ...
    } finally {
        outputStream.close();
    }
    
  4. 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!

\$\endgroup\$
  • \$\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 Mar 25 '11 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 Mar 10 '12 at 19:15
  • \$\begingroup\$ @Landei also known as try-with-resources. \$\endgroup\$ – Adam Oct 26 '12 at 23:24
2
\$\begingroup\$

@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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.