Asish AP
Asish AP

Reputation: 4441

Imageview and OutOfMemory in Android

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

Upvotes: 1

Views: 1448

Answers (2)

Ognyan
Ognyan

Reputation: 13600

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.

Upvotes: 1

Kristiono Setyadi
Kristiono Setyadi

Reputation: 5643

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.

Upvotes: 0

Related Questions