-1

I am trying to fetch string of bytes and want to convert it to pdf in android app and showing that pdf.

I am writing the bytes in sdcard.

The web service is using ksoap2-android-assembly-2.6.1-jar-with-dependencies.jar.

Following method is in Webservice.java class.

public static <T> T GetAttachmentasbinary(int id,String AttachmentType, String METHOD_NAME) {
    //String resTxt = null;
    // TODO Auto-generated method stub
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

    PropertyInfo PI = new PropertyInfo();
    PI.setName("Industry_Id");
    PI.setValue(id);

    PropertyInfo At = new PropertyInfo();
    At.setName("AttachmentType");
    At.setValue(AttachmentType);

    request.addProperty(PI);
    request.addProperty(At);

    T result = null;
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER11);
    envelope.dotNet = true;
    // Set output SOAP object
    envelope.setOutputSoapObject(request);
    // Create HTTP call object
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

    try {
        // Invole web service
        androidHttpTransport.call(SOAP_ACTION+METHOD_NAME, envelope);
        // Get the response
        //SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
        // Assign it to fahren static variable
        //resTxt = response.toString();
        try {
        result = (T) envelope.getResponse();
        }
        catch (SoapFault e) {
            e.printStackTrace();
        }

    } catch (Exception e) {
        e.printStackTrace();
        //resTxt = "Error occured";
    } 

    return result;
}

Following code is the thread

private class AsyncCallWS2 extends AsyncTask<String, Void, Void> {
    protected Void doInBackground(String... params) {
        String strBinaryPDFString = WebService.GetAttachmentasbinary(I_id,txt,"GetAttachmentasbinary").toString();
          File createfile = new File(Environment.getExternalStorageDirectory(),"/");
          createfile.mkdirs();
          File outputFile = new File(createfile,"FileName.pdf");//creating temporary file in phone Memory
                  try {
                        new FileOutputStream(outputFile);
                        byte[] bytes = Base64.decode(strBinaryPDFString,Base64.DEFAULT);
                        File filepath = new File(Environment.getExternalStorageDirectory(),"/FileName.pdf");
                        OutputStream pdffos = new FileOutputStream(filepath);
                      try {
                          Log.d("Writing ","bytes");
                        pdffos.write(bytes);
                        pdffos.flush();
                        pdffos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                } catch (FileNotFoundException e1) {
                    e1.printStackTrace();
                }
      Intent intent = new Intent(FieldActivity.this, myPDFActivity.class);
      intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME,Environment.getExternalStorageDirectory()+File.separator+"FileName.pdf");
      startActivity(intent);
        return null;
    }
}

I am calling it through click event of button of listview as below.

    @SuppressWarnings("resource")
public void click(View v) {

      final int position = getListView().getPositionForView(v);
      String text = getListView().getItemAtPosition(position).toString();
      txt = text.substring(text.toString().lastIndexOf("=")+1, text.length()-1);

      AsyncCallWS2 task = new AsyncCallWS2();
      task.execute();
    }

This code is running fine for small files but for one large file which is around >=30 mb of size it is showing following error

3-19 13:14:43.864: I/dalvikvm-heap(350): Grow heap (frag case) to 27.276MB for 11647500-byte allocation
03-19 13:14:44.014: D/dalvikvm(350): GC_FOR_MALLOC freed 8530K, 49% free 14356K/28039K, external 2437K/3044K, paused 45ms
03-19 13:14:44.304: D/dalvikvm(350): GC_CONCURRENT freed <1K, 49% free 14356K/28039K, external 2437K/3044K, paused 27ms+24ms
03-19 13:14:45.354: D/dalvikvm(350): GC_FOR_MALLOC freed 5K, 49% free 14356K/28039K, external 2437K/3044K, paused 42ms
03-19 13:14:45.354: I/dalvikvm-heap(350): Forcing collection of SoftReferences for 9431460-byte allocation
03-19 13:14:45.404: D/dalvikvm(350): GC_FOR_MALLOC freed 38K, 49% free 14317K/28039K, external 2437K/3044K, paused 48ms
03-19 13:14:45.404: E/dalvikvm-heap(350): Out of memory on a 9431460-byte allocation.
03-19 13:14:45.404: I/dalvikvm(350): "AsyncTask #4" prio=5 tid=12 RUNNABLE
03-19 13:14:45.404: I/dalvikvm(350):   | group="main" sCount=0 dsCount=0     obj=0x4071e148 self=0x334b28
03-19 13:14:45.404: I/dalvikvm(350):   | sysTid=362 nice=10 sched=0/0     cgrp=bg_non_interactive handle=4683016
03-19 13:14:45.404: I/dalvikvm(350):   | schedstat=( 16356500657 1719596168 647 )
03-19 13:14:45.404: I/dalvikvm(350):   at java.lang.String.<init>(String.java:~513)
03-19 13:14:45.404: I/dalvikvm(350):   at org.kxml2.io.KXmlParser.get(KXmlParser.java:610)
03-19 13:14:45.404: I/dalvikvm(350):   at     org.kxml2.io.KXmlParser.getText(KXmlParser.java:1280)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.serialization.SoapSerializationEnvelope.readUnknown(SoapSerializationEnvelope.java:256)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:422)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.serialization.SoapSerializationEnvelope.readUnknown(SoapSerializationEnvelope.java:289)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:422)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:149)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:137)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.transport.Transport.parseResponse(Transport.java:100)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:195)
03-19 13:14:45.404: I/dalvikvm(350):   at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:95)
03-19 13:14:45.404: I/dalvikvm(350):   at com.example.downloadfromwebserviceexample.WebService.GetAttachmentasbinary(WebService.java:157)
03-19 13:14:45.404: I/dalvikvm(350):   at com.example.downloadfromwebserviceexample.FieldActivity$AsyncCallWS2.doInBackground(FieldActivity.java:77)
03-19 13:14:45.404: I/dalvikvm(350):   at com.example.downloadfromwebserviceexample.FieldActivity$AsyncCallWS2.doInBackground(FieldActivity.java:1)
03-19 13:14:45.404: I/dalvikvm(350):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-19 13:14:45.414: I/dalvikvm(350):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
03-19 13:14:45.414: I/dalvikvm(350):   at java.util.concurrent.FutureTask.run(FutureTask.java:138)
03-19 13:14:45.414: I/dalvikvm(350):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-19 13:14:45.414: I/dalvikvm(350):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-19 13:14:45.414: I/dalvikvm(350):   at java.lang.Thread.run(Thread.java:1019)
03-19 13:14:45.414: W/dalvikvm(350): threadid=12: thread exiting with uncaught exception (group=0x40015560)
03-19 13:14:45.424: E/AndroidRuntime(350): FATAL EXCEPTION: AsyncTask #4
03-19 13:14:45.424: E/AndroidRuntime(350): java.lang.RuntimeException: An error occured while executing doInBackground()
03-19 13:14:45.424: E/AndroidRuntime(350):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.FutureTask.run(FutureTask.java:138)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.lang.Thread.run(Thread.java:1019)
03-19 13:14:45.424: E/AndroidRuntime(350): Caused by: java.lang.OutOfMemoryError
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.lang.String.<init>(String.java:513)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.kxml2.io.KXmlParser.get(KXmlParser.java:610)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.kxml2.io.KXmlParser.getText(KXmlParser.java:1280)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.serialization.SoapSerializationEnvelope.readUnknown(SoapSerializationEnvelope.java:256)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:422)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.serialization.SoapSerializationEnvelope.readUnknown(SoapSerializationEnvelope.java:289)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.serialization.SoapSerializationEnvelope.read(SoapSerializationEnvelope.java:422)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:149)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:137)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.transport.Transport.parseResponse(Transport.java:100)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:195)
03-19 13:14:45.424: E/AndroidRuntime(350):  at org.ksoap2.transport.HttpTransportSE.call(HttpTransportSE.java:95)
03-19 13:14:45.424: E/AndroidRuntime(350):  at com.example.downloadfromwebserviceexample.WebService.GetAttachmentasbinary(WebService.java:157)
03-19 13:14:45.424: E/AndroidRuntime(350):  at com.example.downloadfromwebserviceexample.FieldActivity$AsyncCallWS2.doInBackground(FieldActivity.java:77)
03-19 13:14:45.424: E/AndroidRuntime(350):  at com.example.downloadfromwebserviceexample.FieldActivity$AsyncCallWS2.doInBackground(FieldActivity.java:1)
03-19 13:14:45.424: E/AndroidRuntime(350):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-19 13:14:45.424: E/AndroidRuntime(350):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
03-19 13:14:45.424: E/AndroidRuntime(350):  ... 4 more
03-19 13:15:10.274: I/Process(350): Sending signal. PID: 350 SIG: 9

I added

android:largeHeap="true"

in AndroidManifest.xml file. so it growing the heap but the string variable which is storing the bytes strings from web service is exceeding the limit.

What can be the solution here?

I updated ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar and now error is changed to

Caused by: java.lang.OutOfMemoryError at org.kxml2.io.KXmlParser.push(KXmlParser.java:626)

prem30488
  • 2,828
  • 2
  • 25
  • 57
  • 1
    A 9 MB string? Looks like an XY problem; what if you explained what you wanted to do instead? – fge Mar 19 '14 at 07:56
  • my code is working for small files and not working for large files.i want it to work for large files. – prem30488 Mar 19 '14 at 08:56

1 Answers1

1

You are doing this the wrong way - if you want to transfer large objects, use direct HTTP links. This way, you will be able to write them directly to the SD card while they are getting received, and not use up multiples of their size in main memory.

Again, do not send them as attachments from the web service, send them as direct http responses - I believe there's even a WS-* compatible way to specify that.

Tassos Bassoukos
  • 16,017
  • 2
  • 36
  • 40