My activity have several static bitmap arrays,but sometimes those static bitmap is gone when i open other activity, such as load photo using the intent below:
My Code
Intent intent = newIntent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ACTIVITY_SELECT_IMAGE);
When i stay too long in intent which i call to pick image, all my static bitmap array is gone.. i can't use final static because i change those bitmap on run time..
How do i prevent this? Thanks.
Android offers no guarantees on static references like that. The reason that it sometimes works and sometimes not is basically because sometimes the garbage collector(GC) has set your array to null and sometimes not. The GC will not set your reference to null if you activity is active, but it will if it has to when your activity is inactive, e.g. not visible.
You need to add a check for null in the onResume() method and make a new Bitmap array if necessary. As for the bitmaps themselves that are stored in the array, you need to store them in memory. Check the following article and read about saving cache files via the getCacheDir() method. That is basically what you need since the data does not need to be stored persistently across multiple sessions.
http://developer.android.com/guide/topics/data/data-storage.html
Related
I'm developing Web-client on Android. I use IntentService for http-request. As a result, the object are formed by IntentService which have not only the primitive types, but also, for example, Bitmap object field. Tell me, please, best way to pass the object in the Activity, or some another class.
I try used ResultReceiver, but callback method get only Bundle-object:
void onReceiveResult (int resultCode, Bundle resultData)
Bundle-object is only suitable for storing simple types. Translate large Bitmap-object as byte array is not recommended.
The second path, that to pack the object in the Parcel and set in Intent. Then catch it using BroadcastReceiver. How about sending large object in Broadcast message?
Perhaps you can just save the image and pass through the OutputStream way? Or just save it as a static variable somewhere? I'm not an expert of Android, the main thing I want to get fast app. Thanks for your answers!
Bundle-object is only suitable for storing simple types. Translate large Bitmap-object as byte array is not recommended.
Yes, you should never transfer large data via Intent. It's not about data type, it's about size.
The second path, that to pack the object in the Parcel and set in Intent. Then catch it using BroadcastReceiver. How about sending large object in Broadcast message?
It's same thing, sending a message still requires Intent which has limitations.
Or just save it as a static variable somewhere?
This will work but this is a bad architecture. If you do this you will always have to think about that static field and be sure at all times that you are not keeping a static reference to the Bitmap you no longer need. I strongly don't recommend this.
Instead, you can store your Bitmap object to disk and then read it in your Activity. Here is an example: Save bitmap to location
I am trying to access an image in another activity (say B) which is being captured in activity(say A). Now here, I have two options:
1. Save to sd card and then access in activity B through the filepath.
But, time taken to save is higher in some cases, probably because of higher
image size.
2. Send the bit array through intent.putExtra("imageArray" , data) and access it
in activity B through getIntent(). But on surfing net, I found sending bigger
bitmap of 1MB or more is a bad practise but didn't find anything with regards to
bitarray.
Can someone suggest me which option is better ? And is sending a bitmap of greater size as bitArray to another activity a bad practise ?
My requirement is : time lag between two activities A and B should be minimum. Also, image should be loaded in activity B in no time.
Thanks in advance.
Also you can use global variables in Application space (singleton).
Example:
public class YourApplication extends Application
{
private static YourApplication singleton;
Bitmap bitmap; // or any type, byte array
....
public static YourApplication getInstance()
{
return singleton;
}
}
...
in another class you can set and get this variable 'bitmap':
YourApplication.getInstance().bitmap = ....; // in Activity A
or
... = YourApplication.getInstance().bitmap; // in Activity B
or use inside another method
....( ..., YourApplication.getInstance().bitmap, ...);
If you load the image both in activity A and activity B by using a URL you can use ion - https://github.com/koush/ion. It helps you show pictures using a URL and it caches your image, so that loading it again happens instantly, just send the url from activity A to activity B.
If you use the phone camera to capture a image I would say that saving it is the better way to go, if your gonna want to send many pictures at once in the future the second option will be bad.
I am using LRUCache to download images from server and showing on my activity views. I am not saving these images permanent storage(e.g. SD Card).
My Problem is that as my orientation changes, my LRUCache's object is destroyed and i am not able to get the images back after orientation change.
Before using the LRUCache i was storing the images in bundle, and hence, using onSaveInstanceState(bundle) it was easy to deal with that problem. But how to do like this with LRUCache object. Help!
Easiest way is to use a Fragment for that page. Then you can do setRetainInstance(true); to keep the OS from destroying the fragment on a config change.
Another way is to put the LruCache in an Application derived class. This is one way to keep persistent data between Activities too.
In onSaveInstanceState, try using LruCache.snapshot() to get a Map of your cache entries, ordered from least to most recently used. You could then write each key,value into the Bundle. Then when restoring from the Bundle, iterate each entry and put() them back into the LruCache.
Make a separate Class which contain a static variable holding your LRU class, your LRU will not be destroyed because it is a separate reference.
class MyLRU {
public static LruCache<String, Bitmap> mMemoryCache = new .....
}
To call the cache from your activity:
Bitmap myImage = MyLRU.mMemoryCache.get("imagekey");
I'm trying to just keep a Bitmap in memory for the next activity to use without putting it in the extras bundle due to its size or saving it to the sd card for performance issues. Is there any way to pass a reference to my Bitmap to another activity.
I want to do something like this
Bitmap myBitmap = null;
Intent newIntent = new Intent(thisClass.this, nextActivity.class);
newIntent.putExtra("bitmap", reference to myBitmap);
If I pass the full bitmap it crashes because the file is over 1MB in size, so I just want to pass a reference or possibly contain the file in another class and serialize it or something I'm not sure what to do.
You can put the bitmap in the Application Context.
The "Intent" will not pass the reference, but to serialize and deserialize the bitmap object.
After going through few articles about performance,
Not able to get this statement exactly.
"When a Drawable is attached to a view, the view is set as a callback on the drawable"
Soln: "Setting the stored drawables’ callbacks to null when the activity is destroyed."
What does that mean, e.g.
In my app , I initialize an imageButton in onCreate() like this,
imgButton= (ImageButton) findViewById(R.id.imagebtn);
At later stage, I get an image from an url, get the stream and convert that to drawable, and set image btn like this,
imgButton.setImageDrawable(drawable);
According to the above statement, when I am exiting my app, say in onDestroy()
I have to set stored drawables’ callbacks to null, not able to understand this part ! In this simple case what I have to set as null ?
I am using Android 2.2 Froyo, whether this technique is required, or not necessary.
You would have to do this only if you kept the drawable as a static field somewhere, or in a cache of some sort. In this particular situation, there's no reason to set the callback to null.
Here is exactly what was the case in example you cited:
Phone orientation has been changed, and this should mean that old activity should be "dumped" and new one created
If you have stored reference to bitmap as a static field, it has reference to old activity that was supposed to be dumped (drawable has reference to TextView, view has reference to activity)
New activity is created, but your drawable still has the reference to old one, so old one can't be dumped.
Of course, all this is right if you store drawable as static like in cited example:
private static Drawable sBackground;