1

Hi Stackoverflow friends,

I need an appliaction that ,capture an image using camera and display it in an image view repeatedly.After taking the picture i send this picture to the server.For this process i'm using AsynTask class named myBackgroundUploader. When i click the button i calls the Asysnctask.I done it but after taking 2 three pictures I got outofmemory error and my app force closed. I tried to recycle(),null values but no use. Can any one tell how to avoid this error .This is the log i have got.

    onCreate()
    {
    setContentView(R.layout.detail_profile);

    String fname=new File(getFilesDir(), "MyFile.jpeg").getAbsolutePath();
     if(imgView!=null)
               {
                   imgView.destroyDrawingCache();
               }
                imgView=(ImageView)findViewById(R.id.imageView1);
                imgView.setImageURI(Uri.fromFile(new File(fname)));

    }


public void onClick(View v) {

                 if(checkInternetConnection()==false)
                {
                     new AlertDialog.Builder(detailProfile.this).setTitle("Warning!").setMessage("No Internet connection").setIcon(R.drawable.icon).setNeutralButton("Close", null).show();

                }   if(diTask!=null)
                        {
                            AsyncTask.Status diStatus=diTask.getStatu();
                            if(diStatus!=AsyncTask.Status.FINISHED)
                            {
                                return;
                            }

                        }
                        fileprocess();
                        diTask=new myBackgroundUploader(detailProfile.this);
                        diTask.execute("url for server");

}

 myBackgroundUploader.java

protected void onPreExecute()
    {

        progDailog = ProgressDialog.show(mcontext,
                "Syncing with server ", "Please wait....",
                true);

    }
    protected Bitmap doInBackground(String...pram)
    {
        Log.v("doback","uploading,,");

        uploadImage(pram[0]); //here parm[0]is my server url
        return null;

    }
    protected void onPostExecute(Bitmap bm)
    {

    }

    public void uploadImage(String...urls)
    {
         String fname=new File(mcontext.getFilesDir(),"MyFile.jpeg").getAbsolutePath();
Bitmap testAB=null;
        BitmapFactory.Options options= new BitmapFactory.Options();
        options.inSampleSize = 4;
        testAB=BitmapFactory.decodeFile(fname, options);


        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        testAB.compress(Bitmap.CompressFormat.JPEG,50, bao);
        byte [] ba = bao.toByteArray();
        String ba1=Base64.encodeBytes(ba);
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("image",ba1));
        nameValuePairs.add(new BasicNameValuePair("address",detailProfile.address.getText().toString()));


        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(urls[0]);
        HttpParams param=new BasicHttpParams();
        HttpConnectionParams.setSoTimeout(param, 60000);
        httppost.setParams(param);
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        is =entity.getContent();
        progDailog.dismiss();
        //urls[0].recycle();
        ba=null;
        ba1=null;
        bao.flush();
        testAB.recycle();


      }



07-25 15:39:38.613: ERROR/dalvikvm-heap(31423): 9830400-byte external allocation too large for this process.
07-25 15:39:38.640: ERROR/GraphicsJNI(31423): VM won't let us allocate 9830400 bytes
07-25 15:39:38.640: DEBUG/dalvikvm(31423): GC_FOR_MALLOC freed 1K, 48% free 2904K/5511K, external 21335K/23354K, paused 16ms
07-25 15:39:38.644: DEBUG/skia(31423): --- decoder->decode returned false
07-25 15:39:38.656: WARN/dalvikvm(31423): threadid=9: thread exiting with uncaught exception (group=0x40015560)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423): FATAL EXCEPTION: AsyncTask #1
07-25 15:39:38.664: ERROR/AndroidRuntime(31423): java.lang.RuntimeException: An error occured while executing doInBackground()
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at java.lang.Thread.run(Thread.java:1019)


07-25 15:39:38.664: ERROR/AndroidRuntime(31423): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:284)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:309)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.uploadImage(myBackgroundUploader.java:133)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.doInBackground(myBackgroundUploader.java:57)
07-25 15:39:38.664: ERROR/AndroidRuntime(31423):     at com.rodasys.profile.myBackgroundUploader.doInBackground(myBackgroundUploader.java:1)

Thanks in Advance

Jeff Foster
  • 43,770
  • 11
  • 86
  • 103
Asish AP
  • 4,421
  • 2
  • 28
  • 50
  • 1
    Without code sample is hard to gues where the problem is. But probably You have memory leak somewhere – matekm Jul 25 '11 at 10:32
  • I've experienced this many times. Please post your code here so everyone can help you out of trouble. – Kristiono Setyadi Jul 25 '11 at 10:38
  • Hi matekm I updated my question and add my code. – Asish AP Jul 25 '11 at 10:47
  • hi Kristiono Setyadi I updated my question and add my code – Asish AP Jul 25 '11 at 10:48
  • take look might help http://stackoverflow.com/questions/4102758/outofmemory-exception-when-loading-bitmap-from-external-storage/4134307#4134307 and http://stackoverflow.com/questions/1147172/what-android-tools-and-methods-work-best-to-find-memory-resource-leaks – Avi Kumar Jul 25 '11 at 10:49
  • Are you using any static fields in your activity? Like caching the images for example? – Ognyan Jul 25 '11 at 11:15
  • yes imageview is a static fileld. public static ImageView imgView; – Asish AP Jul 25 '11 at 11:20

2 Answers2

1

yes imageview is a static fileld. public static ImageView imgView

It seems that is the problem which causes memory leak and consequently low memory. You may want to read this excellent article about how to avoid it: http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/

In short: don't use static instance variable. You should be fine by removing static (if it does not hurt your code's logic), otherwise you will have to redesign the activity without static field containing ImageView.

Ognyan
  • 13,452
  • 5
  • 64
  • 82
0

I think you should do the recycle before any heavy operation of the image. So instead of doing what you've done, I suggest you to try this:

if (testAB != null) {
    testAB.recycle();
}

// do your heavy image operation here

Don't forget to use a background process such as AsyncTask when doing something to your image, especially when you assign an image to a UI element, e.g. ImageView.

And try to put the decoded image into your ImageView instead of the original one which probably always has the bigger size than the decoded one.

Let me know if this work for you.

Kristiono Setyadi
  • 5,635
  • 1
  • 19
  • 29