0

In a thread i'm fetching a jpg image (from a socket) and putting it in a byte array datas[]. Then i make a bitmap and send it to my ui to display it in an imageview :

Thread side :

bundle.putParcelable("image", BitmapFactory.decodeByteArray(this.datas, 0, jpgSize,this.bitmapOption));
message.what = ThreadMessages.MSG_IMAGE_AVAILABLE;
message.setData(bundle);
this.uiHandler.sendMessage(message);

The bitmap option is defined as following :

this.bitmapOption = new BitmapFactory.Options();
this.bitmapOption.inPurgeable = true;

ui side :

cameraView.setImageBitmap((Bitmap) bundle.getParcelable("image"));

As far i know it's works fine on phone with android 2.x and 4.0.x. But i have made some test with a galaxyTab 8.9 (android 3.1) and my activitie is killed by the system due to a high memory usage :

01-30 14:12:02.311: I/ActivityManager(72): Process my.package (pid 1175) has died.
01-30 14:12:02.321: I/WindowManager(72): WIN DEATH: Window{41140848 my.package/my.package.DisplayOneCam paused=false}
01-30 14:12:02.331: I/WindowManager(72): WIN DEATH: Window{410f5020 my.package/my.package.main paused=false}
01-30 14:12:02.331: I/WindowManager(72): WIN DEATH: Window{41033308 my.package/my.package.DisplayCameras paused=false}
01-30 14:12:02.371: I/ActivityManager(72): Start proc my.package for activity my.package/.DisplayCameras: pid=1209 uid=10036 gids={3003, 1015}
01-30 14:12:02.371: I/ActivityManager(72): Low Memory: No more background processes.
01-30 14:12:02.391: I/WindowManager(72): WINDOW DIED Window{410f5020 my.package/my.package.main paused=false}

The fetched bitmap is not a very high res pictures (800*600 max) but it is displayed at least at 10 fps (more if it's possible). Using the inPurgeable option lets me avoid the OOM crash (i had it before using inPurgeable) but it not seem to be enough . Using inSampleSize (like explained in Strange out of memory issues) don't seems to be a solution because it resize the image, and i need a image which take the entire space of the imageview.

How can i improve my memory usage knowing that i'm receiving a jpg in a byte array and i need to display it in a imageview ?

Note : i don't need/want to resize the bitmap, the received jpg is already well sized.
Note 2 : Triggering system.gc() after each decodeByteArray seems to solve th eproblem, but it's ugly and performance are slowing down drasticly

Community
  • 1
  • 1
grunk
  • 14,718
  • 15
  • 67
  • 108

2 Answers2

2

Using Parcelable to send large amounts of data in Intents is a bad idea and is likely to result in poor performance. You would be better to store the image to persistent storage, and pass a URI to the stored image instead of the image data itself.

There is some more info on this in how do you pass images (bitmaps) between android activities using bundles?

Community
  • 1
  • 1
Mark Allison
  • 21,839
  • 8
  • 47
  • 46
  • I can't store the image : i'm displaying at least 10 images per second. Writing, reading and deleting image will be a way to long. I could eventually decode the byte array in the activity but that's all. – grunk Jan 30 '12 at 15:59
  • Persisting to a bundle and reversing the process at the other end is likely to be slower than writing to SD card and reading back again. If you don't want to d that why not store the image in the Application instead? – Mark Allison Jan 31 '12 at 11:40
0

There is no need to use a Bundle if you're only passing the Message within your application process. Simply pass your Bitmap in Message.obj.

Karsten
  • 310
  • 1
  • 6