Saturday, June 7, 2014

Avoiding Out of Memory errors while loading large bitmaps

Hi everyone! Has been a long time since I wrote here, and it is time to clean the dust and publish new and hopefully useful stuff :)
Today I will present some suggestion on how to minimize the amount of RAM while loading large bitmap on Android, in order to avoid the common OutOfMemory error.

New mobile phones and tablets have constantly seen their display to become more capable in term of display resolution. This brings many positive aspects, but for developers, usually a lot of headaches: more capable displays means much more memory required to display images and pictures on them.

An image (a PNG, a JPEG..) is always displayed as a matrix of pixels. Supposing a 32 bit depth color, each pixel is represented as 32 bits, i.e. 4 bytes (R,G,B and alpha component).
On a modern display (for example, let's take the Nexus 5), we have 1080x1920 pixels. Potentially, an app that shows an image fullscreen (for simplicity we pretend the black bar with status bar and Android system buttons is hidden) must load in memory a bitmap: 4 * 1080 * 1920 = 8294400 bytes big.

This would not be a problem if the only thing loaded in the current instance of dalvik VM is that image, but of course in memory we can have much more objects.

How much memory does Android borrow to a single app? It depends. Each Android device might in theory have a different threshold which dictates how much memory is granted to the application. It is declared as a system property and can be read by typing this on the console:

adb pull /system/build.prop
cat build.prop

and checking the property dalvik.vm.heapgrowthlimit 
In general, devices with bigger dpi screens have a higher value of heap limit. For example, the LG Nexus 5, a XXHDPI device, has 192MB of limit. As said, device with the same resolution might have different heap limit: an HTC One X (XHDPI device) has 92MB of limit; a Samsung S3 (also XHDPI) has only 64MB of heap limit.

An app can request more RAM, by declaring the android:largeHeap property in the Android manifest. How much RAM can be granted? Also this property is defined in the same file (dalvik.vm.heapsize), and in case of my Nexus 5, is 512 MB.
Why not just using always this property? Because the GC tends to become inefficient and app will be much slower. 

Consequently, in mostly all cases, instead of setting this attribute we need to minimize the amount of RAM needed, especially if we want to tackle the well known OutOfMemory exception.

In order to minimize the possibility of such error, a well-behaving app that need to load a large bitmap must:
- check the amount of free memory left 
- adopt strategies in case the available memory is not enough to load it.

Check the amount of free memory left

Android inherits the Runtime clas sfrom Java standard library. This helps getting the information we fetched via console: in particular, how much memory is available, how much free memory is left before the VM will complain.

In the gist above, I calculate the total available heap (192MB on my device) and the available heap (it was around 175MB before loading the bitmap).

Check how big is the bitmap we want to load

On Android3.0+, we can use a handy class called BitmapFactory.Options. It does a lot of useful things, one of which is giving info about the image, without loading it in memory.

In the snippet above, I use the aforementioned class to calculate image width and height without loading it in RAM, by setting to true the inJustDecodeBounds property. We can have a rough aestimate of how large will be the image in RAM from its width, height attributes.

Load a subscaled version of the bitmap in RAM

If the memory available is less than the amount of memory required by the bitmap, then we apply some subsampling. The image will be imperceptibly lower in quality on the specific device where this subsampling will happen, but we will avoid the Out of Memory error. User will be happy and probably won't even notice the difference.
Again, to subsample the image we use the BitmapFactory.Options:

We use power of 2 because the decoder will anyway round other values to a power of 2. Also, I placed a limit o 8 but also this can be avoided and image can be subsampled at any level.

By subsampling an image with a factor of 2 you can see you will be able to spare almost 75% of memory, and the difference in quality is almost negligible.

You can download the sample app which contains all these snippets and a demo activity you can play with here: https://github.com/nalitzis/TestMemoryViews

Friday, July 26, 2013

Asynchronous code testing in Android

Testing asynchronous calls it is not always an easy task.

Let's take as reference this simple interface:


The first thing is: how can we test it through an Android unit test class?


We can't test the value inside the callback. Infact, an async call runs usually in worker thread. When the thread has done some computation, it calls the callback. The simplest case is when the callback is run in the same worker thread.

But still, we need to find a way to block the main thread, otherwise the test class will simply don't wait before the callback is called! Remember that the method testDoSync() is called in the main thread.

We can use a semaphore, and make the test method wait until the callback is delivered. Then we can easily test the return value. The Semaphore class has some interesting properties: first, we can use it to put a thread in wait; the acquire() method stops the thread until a resource is available. As we have created the Semaphore with 0 resources available, this will cause the next call to acquire() to stop the thread.
But what if there is the unlikely case that the listener, returns before the acquire() call is made? No worries, as the signal() will simply increment the number of resources available and so the acquire() method will not nlock but will return straight away. Yay, this is for sure a better way to handle threads synchronization that the usual pattern wait-notify!
This is the code that covers this case:


And now, the worst case. Let's imagine that the code run by the worker thread do some stuff, and then it posts the results of its work in the calling thread (for instance through a handler). Then, onValueChanged() will never be called. Why? It is because we needed to stop the main thread. The main thread is a looper thread: normally a thread do some stuff and then it dies. Instead, a thread with a looper processes events by looping continuously. Another thread can post events on it: the events are put in the thread queue and they are processed one at time. If we block the main thread, the event posted by the worker thread will NEVER get processed.
How to handle this case?
We still need to block the main thread. But we need to launch the callback from a secondary thread with the looper.
We will use a facility offered by android: HandlerThread.

It will create a thread with looper for us; then the callback will be called in the secondary thread looper that is not blocked, and from that thread we can release the semaphore of the main thread.
Finally, remember to quit() the thread handler (that will quit the embedded looper too and will cause the death of that thread).

Friday, July 12, 2013

Dynamic resize of views and offscreen view size calculation in LinearLayout

The layout is usually handled by a set of xml files, where we specify how the components of our view group are displayed.
It should be the preferred way of generating and composing the views. It is possible to merge layouts, to inflate custom views etc.
There are some occasions, though, where the xml syntax and attributes are not powerful enough.
For example, we can have a vertical linear layout where, at some point, we inflate a custom view. We don't know how big (and, above all), tall is this view at compile time. The problem is, all or some views below it can disappear because our "big" view takes all available space.

A solution might be to wrap the views in a relative layout. All good, all fine, in that way we can specify that the big view must be below a child, and above another. Then we align the first view to the top, and the last to the bottom.

But the problem is that the height of the relative layout can't be wrapped!
As stated also in the documentation (which should have read before spending a couple of hours in adapting the layout :P)
Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.
The only way is adjusting the layout at runtime: we must calculate the height of the big view  and if its bottom point is at the end of the layout and there are still views to draw, then we need to calculate their value and resize it accordingly.

A problem is that we can't get simply the height of the offscreen views! Since they are offscreen, Android will give us 0 as the height.

What we can do, is using the class called View.MeasureSpec and calculate the view size like this:



Then, we need to find a way to adjust the size of the big view; again, we can't do that in onCreate() or other similar callbacks, as the view is not rendered yet and we will get 0 as height of the view.
We could override the View.onMeasure() method but as it gets called multiple times by the framework, it is not very reliable.
Best thing is adding a ViewTreeObserver and do all the calculations in its callback:



The code of this example is available here:
https://github.com/nalitzis/TestDynamicViews




Friday, April 5, 2013

Threads signaling mechanisms in Java

In Java, there might be situations where you want to perform an operation on a certain thread and then, the same thread should wait for a certain condition before completing its task. This condition happens after another thread completes its execution.

For instance, we want to run a syncronous method on thread-1:





A first option to do this is by using the wait() and notify() methods provided by Object class.
The first thread calls wait() and the callback thread calls notify().


We must be carful though, because if the notify() method happens-before the wait() one, the waiting thread will wait forever.

To prevent this, we need a boolean variable, that can be used to prevent a similar scenario:





It is also possible to use Semaphore class, from java.util.concurrent package and call acquire() and release() methods to do the same thing.

Take a look also at this interesting tutorial that deals with many important Java concurrency topics:
http://tutorials.jenkov.com/java-concurrency/index.html

Friday, February 8, 2013

Inter Process Communication on Android: Binders and Aidl

In contrast with iOS, where an app can be responsible for only one process at a time, Android provides many ways to create an app which spawns two or many processes. On Android instead, there is the possibility for two different apps (i.e. two different apks) to communicate, or two processes that live in the same apk but in different processes.
In both cases, the system must provide a "channel" that allows two processes to communicate. In contrast with threads, two processes don't share memory for data, therefore the system must provide a way for the data to cross the process boundaries.

Historically, have been defined many ways to create a communication between two processes (for example, CORBA, or JRMI); Android has defined its own implementation: it is called AIDL, and the acronym stands for Android Interface Definition Language.

This blog post describe how to create a simple application that spawns two processes, and in detail shows two ways to implement it. The first is through the Messenger class and in many cases it is enough powerful, the second one is more low level, but requires to implement an AIDL interface. In detail, there is a simple Activity that lives in a process (the process where the app lives) and two services. Both the services are remote; the first one communicates with the activity via a Messenger, the second via the AIDL.


In the code above, there is the important part of the manifest, where the two services are declared. As we can see, to declare a service as remote, we must specify the android:process attribute. The exported attribute tells the system if a component can be exposed to other applications; in case it is true, another app can launch the component. But this is not relevant in our context.


IPC with Messenger and Handler


This mechanism allows two process to communicate and save the developer from creating AIDL files and it is more simple and straightforward; the system under the hood however will use AIDL but the developer doesn't see it.

In the code above, it is shown how the service is created and bound.

In the code above, it is shown how the remote service is implemented. If the service is remote, we must implement the method onBind(); the three fundamental components are: binder, messenger and handler.
The service use a handler, used to receive data from a remote process; the binder is as its name suggests, the "thing" that binds the two processes.  The messenger is tied to the binder and provides a convenient way for the two sides to communicate effectively. In the example above,  the activity generates a Messenger from the binder received as parameter in the onServiceConnected() callback. It will use the messenger to send data to the remote process (method sendMessage()). In the ClientService.java, the handler is used to receive data from the remote process.

The example shows that the Process ID of the sender is different from the process ID of the receiver and the string sent from the activity is correctly received from the service, that lives in its own process.

IPC with AIDL

If we want to use AIDL, we must first specify an interface between the client process and the server one; it is a file with methods shared between the client and the server. These methods are the "entry points" for a process to start the communication with the other process.
In our case, the scenario is very simple. The aidl file contains only a method (multiply) that multiplies two numbers. The service will take care of the mathematical operation. In the example we don't return a value to the client, but of course it can be done.
When we define an aidl file, the system will generate the relative implementation in the /gen directory. If you have a look at the implementation, it is easy to spot what happens under the hood: the data which have been serialized before the dispatch, are then received as a Parcelable object, deserialized and then the method at the server side (in this case multiply) is finally called.




The service implements the Stub (defined as an abstract class in the auto-generated file); the Stub is also the binder (extends Binder).
The activity retrieves the interface to communicate with the server via this method:
multiplierService = IMultiplier.Stub.asInterface(service);
It returns a client-stub that has the same interface as the counterpart implemented at the server side (AidlService).
When we have the instance, we can banally call the multiply method as if it were a local method:

multiplierService.multiply(5, 7);

The complete code can be found here:





Sunday, December 23, 2012

Threading, loopers and messaging queues in Android

Android provides an efficient way to allow communication between different threads.
One thread can communicate with another by creating a Message object. Usually a Message is not created with the normal constructor; instead, it is used one of the static factory methods provided by the class, for instance obtain(Handler h, int what, Object data).

One way to send a message to another thread is to create a Messenger object and invoke the send method with the Message to send.
But how can we pass to the messenger which thread will receive the message? In the constructor, it is specified the handler bound to the target thread, i.e. the thread that will receive a messenger. An Handler is an object that, as its name suggests, when created, binds itself with the thread that is creating it.
Consequently, the receiver thread will create the handler, that will be used by the sender thread that calls the send() method with a Messenger object.

This is the basic behavior.
But usually we want that, at least the receiver thread, will be running indefinitely, or at least, as long as we need it running.
We can use a Looper object to transform a simple "one-shot" thread, in a thread that runs indefinitely, or at least, as long as the quit() method is not called, to quit the loop.
The Looper class "enriches" the behavior of a thread in two ways:

  • transforms a thread in an indefinite one
  • creates internally a messaging queue that provides a serialized handling of the messages received. A message received is handled in the handleMessage() method of Handler.Callback.
In the script above, the code between Looper.prepare() and Looper.loop() creates a handler that will handle the messages received by the current thread. If a message is received before the handler has finished processing the message, it will be automatically enqueued and executed as soon as the previous message has been completely processed.


The Handler subclass manages the incoming message. In the example above, it just prints the data received and sleeps for 2 seconds.

I have created a short demo project consisting of a main activity and a looper thread. The looper thread processes in its queue messages sent by the main thread (ui thread) of MainActivity. A message is sent each time the button send is pressed by the user. I have inserted a sleep of 2 seconds in the handler() method of the handler bound to the receiver thread, to show that if a user clicks quickly many times on the send button, the message queue handles the incoming messages sequentially, one after the other.

The demo project can be downloaded from here:
TestLooper

Pleas note that I had to use wait() and notify() methods because the code that trasforms the thread in a looper is not so immediate, so before getting the handler we must be sure that the looper has been created.

Saturday, October 13, 2012

Remove views with nice animations

In iOS is very simple to create effective animations on UI components.

For an app I'm currently working on, I would like to create an animation on a set of views, vertically aligned. When user taps on a button inside the view, the app should start an animation that translates and rotates te view offscreen, while fading it at the same time. At the same time, all the views below it, should react by translating up occupying the space left by the removed view.

This is the initial scenario:



To perform this effect, we need two different animations, one on the view to delete, and the other on the views below it.

This is the first one:


To translate all the views below the one that we want delete, we first need to find them:


 and then we can apply the translation to all of them:


The complete sample project can be found here:
https://github.com/nalitzis/View-delete-animations