0

This is more of a design question. I have a MasterActivity showing a not-so-little preview of an image, and a DetailActivity that should show the image in fullscreen.

Picture is retrieved from server using parse.com services and assigned to ParseImageViews, namely view.setParseFile(file); view.loadInBackground(). Average size is approx. 800x1000px: thus picture is scaled down in master activity, bigger in detail. In both cases I refer to the same 800x1000px file on the backend. Downloading takes some 2s. I do not want to store smaller sizes.

When the user taps a button, I need to pass this Bitmap (ParseFile, objectId, whatever) to DetailActivity, if it was loaded into theMasterActivity.

Option1: Parcelable through Intent

Issue: Binder Transaction Failed

Intent i = new Intent(this, DetailActivity.class);
Bitmap b = ((BitmapDrawable) picture.getDrawable()).getBitmap();
i.putExtra("bitmap", b);
startActivity(i);

Doesn't work, getting Binder Transaction Failed!. It is well documented here on SO (example) that you can't pass objects larger than 1MB (more or less) like that.

Option2: byte[] through Intent

Issue: Binder Transaction Failed

ByteArrayOutputStream stream = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] bytes = stream.toByteArray();
i.putExtra("bitmap", bytes);

As suggested elsewhere I tried to compress the bitmap, but I'm getting the same size error. To avoid transaction limit here I should drop the quality down to 50 or so, and the result is not good to see.

Option3: download the file again in DetailActivity.onCreate()

Issue: OutOfMemoryError

This was a promising option, but didn't work, throwing OOM. My debug opinion is that:

  • I download the image in MasterActivity;
  • I launch DetailActivity, while master is still in the backstack;
  • I download a second instance of the picture, thus going OOM.

I'm stuck at this point. What can I do? If both activities could share the same Bitmap instance, I could avoid OOM.

Community
  • 1
  • 1
natario
  • 24,954
  • 17
  • 88
  • 158
  • Option #4: Don't use separate activities. Use one activity, with separate fragments. Option #5: *Very carefully* pass the image from activity to activity via a static data member, making sure to `null` out that static data member so you do not introduce a memory leak. – CommonsWare Aug 08 '15 at 21:07
  • Save your file in assets directory and then access its. – Vigen Aug 08 '15 at 21:09
  • @Commons I had read about #5 but was reluctant for obvious reasons. Is that what you would suggest? (given that #4 would require some hard work + implying design compromises) – natario Aug 08 '15 at 21:14
  • @Vigen I believe writing+reading a File is like downloading it again - you have the master instance in memory, also, and doubling throws OOM. – natario Aug 08 '15 at 21:16
  • Well, I would have gone with Option #4 from the outset (though note that it doesn't have to involve fragments, just so long as everything is in one activity). That being said, Option #5 should come "for free" from your image-loading library's memory cache. If you're not using an image-loading library or have not configured it's cache, I'd start there. – CommonsWare Aug 08 '15 at 21:17
  • @Commons your configure-your-library clue made it. You can post an answer if you want. – natario Aug 10 '15 at 01:45

0 Answers0