Guava Cache basic demo

25 07 2015

Here I go with the caching! Caching (and cache invalidation) is second one of the most difficult thing to do while programming (the first one is the naming things problem :P ). I’ll show the demo with Guava Cache (18.0). Source Code for this tutorial is on my GitHub: https://github.com/yacekmm/looksok/tree/GuavaCacheDemo/Guava/GuavaCacheDemo

Caches Explained

You may want to get familiar with this article to get the idea of how cache works: https://code.google.com/p/guava-libraries/wiki/CachesExplained.

The Demo Introduction

Here I explain the basic app that accesses data via DAO. Let’s assume that data access is costly so the cache is needed. I want cache entries to expire after specified amount of time. Pretty simple.

Build Cache

Guava provides the cache builder. In my case I make use of it is as follows:

cache = CacheBuilder.newBuilder()
        .expireAfterWrite(5, TimeUnit.SECONDS)
        .build(new CacheLoader<String, String>() {
            @Override
            public String load(String key) throws Exception {
                return dataDao.getValueForKey(key);
            }
        });

I do two things here:

  1. set the desired expiration algorithm and time – entry will become invalid in 5 seconds after it was created or updated
  2. provide the method to load entry – Guava Cache will call this method when you will try to retrieve the value from the cache for the first time (when entry was not found in it yet) or if requested entry has expired. Here that method makes call to my DAO.

Expiration

Among few types of eviction (Size-based, timed, Reference-based) I use Timed eviction, There are two algorythms of expiration in that case. From guava doc:

  • expireAfterAccess(long, TimeUnit) Only expire entries after the specified duration has passed since the entry was last accessed by a read or a write.
  • expireAfterWrite(long, TimeUnit) Expire entries after the specified duration has passed since the entry was created, or the most recent replacement of the value. This could be desirable if cached data grows stale after a certain amount of time.

expireAfterAccess works different. In opposed to expireAfterWrite, it expires entry if it was not accessed in cache in specified time. So if you constatly read that value within its expiration time, it will not get refreshed. expireAfterWrite expires entries based on its age in cache. So it will be refreshed if validity period passed, no matter how freqently you access it (it is done in lazy way, so if time passed, the value will be refreshed only when requested from cache).

Expiration details

In this StackOverflow answer the details are explained by Guava team member:

The Guava Cache implementation expires entries in the course of normal maintenance operations, which occur on a per-segment basis during cache write operations and occasionally during cache read operations. Entries usually aren’t expired at exactly their expiration time, just because Cache makes the deliberate decision not to create its own maintenance thread, but rather to let the user decide whether continuous maintenance is required.

I’m going to focus on expireAfterAccess, but the procedure for expireAfterWrite is almost identical. In terms of the mechanics, when you specify expireAfterAccess in the CacheBuilder, then each segment of the cache maintains a linked list access queue for entries in order from least-recent-access to most-recent-access. The cache entries are actually themselves nodes in the linked list, so when an entry is accessed, it removes itself from its old position in the access queue, and moves itself to the end of the queue.

When cache maintenance is performed, all the cache has to do is to expire every entry at the front of the queue until it finds an unexpired entry. This is straightforward and requires relatively little overhead, and it occurs in the course of normal cache maintenance. (Additionally, the cache deliberately limits the amount of work done in a single cleanup, minimizing the expense to any single cache operation.) Typically, the cost of cache maintenance is dominated by the expense of computing the actual entries in the cache.

The demo and the test

Test mechanism is simple. I set the cache entry expiration time to 5 seconds, and set up a loop to retrieve value from cache each second.

for (int i = 0; i < 20; i++) {
    cacheDemo.getValue("Blue");
    Thread.sleep(1000);
}

I have also added the log line in DAO on each data retrieval and a log line on cache value request. One in five log lines is a log by DAO data retrieval method. The cache value is a string with a timestamp. Notice that it gets updated each time the data is retrieved. This is how console output look like (bold lines are logged by DAO on data request):

Hello, Cache!
returning value from dao: value for key Blue, refreshed from DAO at 20:50:57.559
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:50:57.559
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:50:57.559
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:50:57.559
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:50:57.559
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:50:57.559
returning value from dao: value for key Blue, refreshed from DAO at 20:51:02.700
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:02.700
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:02.700
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:02.700
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:02.700
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:02.700
returning value from dao: value for key Blue, refreshed from DAO at 20:51:07.703
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:07.703
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:07.703
got value from cache for 'Blue': value for key Blue, refreshed from DAO at 20:51:07.703
...

Get the source code

Source code for this demo is on my GitHub: https://github.com/yacekmm/looksok/tree/GuavaCacheDemo/Guava/GuavaCacheDemo

Advertisements




Run gradle project as java application

18 07 2015

gradle run

is not a default task in gradle. To use it, you need to enable the ‘application’ plugin. To enable the plugin add this line to your build.gradle:

apply plugin: 'application'

This plugin requires one variable to be configured – the main class name:

mainClassName = "com.looksok.Main"

Now you can execute the

gradle clean build run

to run your app





Android status bar notifications [complete tutorial with source code]

1 02 2014

Displaying status bar notification is a common way to unobtrusively inform user that something has happened (like new GMail message notification). In your app you can display it whenever you want. I will guide you how to do it from basics. This is how notifications are presented to the user:

Status bar notifications

Status bar notifications

Google’s documentation regarding the notifications is here.

Source Code

All the source code for this tutorial you can download here.

1. Create Basic notification

Notification consists of three obligatory parameters: title text, content text and small icon image. Here is the code that creates such notification:

private Notification createBasicNotification() {
	NotificationCompat.Builder builder = new Builder(getApplicationContext());
	Notification notification = builder
			.setSmallIcon(R.drawable.me)
			.setContentTitle(getString(R.string.notif_title))
			.setContentText(getString(R.string.notif_text))
			.build();

	return notification;
}

2. Display Basic Notification

After it is built, you can display it to the user with NotificationManager:

private void displayNotification(Notification notification) {
	NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
	notificationManager.notify(myNotificationId , notification);
}

Where myNotificationId is final int and is equal to 1:

private static final int myNotificationId = 1;

Thanks to this ID later you can refer to that notification and update its content  or hide it when you need it.

This is how the notification looks like right now:

notif_my_custom

3. Auto Hide notification after it is touched

As for now nothing happens when user touches notification. To make it disappear after touch add this clause to the builder:

setAutoCancel(true)

4. Start activity after notification is touched

The most common action after user selects notification is to open activity presenting the detailed data that caused notification to be issued. You have to assign PendingIntent to notification in order to do it:

private PendingIntent preparePendingIntent() {
	Intent intent = new Intent(getApplicationContext(), MainActivity.class);
	intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

	PendingIntent pendingIntent = PendingIntent.getActivity(
			getApplicationContext(), 
			0, 
			intent, 
			PendingIntent.FLAG_UPDATE_CURRENT);
	return pendingIntent;
}

After that, you assign this intent to notification with the builder command:

.setContentIntent(notificationIntent)

Now you have a basic notification that can issue certain action. Further customization is optional and introduced in newer versions of Android. Since possibilities are quite big, it is worth to continue improving the notification.

5. Filling in remaining small notification fields

Here is the code to fill in the remaining fields of small notification (this should be called on bilder object):

.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.me))
.setContentInfo(getString(R.string.notif_contentInfo))
.setWhen(Calendar.getInstance().getTimeInMillis() + 1000*60+60)
.setVibrate(vibrationPattern)

In order to make vibrations work you need to define pattern (mine is quite sophisticated :P):

long[] vibrationPattern = {0, 200, 800, 200, 600, 200, 400, 200, 200, 200, 100, 200, 50, 200, 50, 200, 50, 200, 500, 200};

but it surely can be simplier:

// Start without a delay
// Vibrate for 100 milliseconds
// Sleep for 1000 milliseconds
long[] pattern = {0, 100, 1000};

and require an VIBRATE permission in android manifest

<uses-permission android:name="android.permission.VIBRATE"/>

6. Apply big style to the notification

What actually is the Big Style? It is the notification with list of String. This is so called InboxStyle, since it is mainy used by GMail to notify user of incoming list of messages. This is how it looks like:

Notice that most of the elements are the same, except the 7 – the details list. Remember that big style works only for android versions higher than or equal to 4.2.

So now – how to build this list? Just create the notificationas it is done until now, and apply style to the builder:

.setStyle(inboxStyle)

And the inboxStyle is built like this:

private InboxStyle prepareBigNotificationDetails() {
	NotificationCompat.InboxStyle result = new InboxStyle();
	result.setBigContentTitle(getString(R.string.notif_inboxStyleTitle));
	result.addLine(getString(R.string.notif_inboxStyle_line1));
	result.addLine(getString(R.string.notif_inboxStyle_line2));
	result.addLine(getString(R.string.notif_inboxStyle_line3));
	result.addLine(getString(R.string.notif_inboxStyle_line4));
	result.addLine(getString(R.string.notif_inboxStyle_line5));
	result.addLine(getString(R.string.notif_inboxStyle_line6));
	return result;
}

Now test it (remember that only android 4.2 or higher will handle such notification). The result is like this:

InboxStyle notification

InboxStyle notification

notice that fields displayed on small notification are not visible in this style.

7. Updating notification content

Notification updates are quite simple: just set the fields you want to change with notification builder and call NotificationManagers’ notify() method providing the ID that you assigned to the notification that you need to update. The notification will be updated accordingly.

Download the Source Code

All the source code for this tutorial you can download here.

Did I help you?
I manage this blog and share my knowledge for free, sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Builder instead of constructor with many (optional) parameters [Effective Java]

21 09 2013

What is it?
Builder is an internal class that is dedicated to build an instance of a type.

When to use it?
It is useful when you have type with optional parameters (that are not always mandatory to provide when creating object). The difference is significant when there is a plenty of params. Then instead of invoking constructor with not all params required:

Type obj = new Type(param1, param2, null, null, null, param6, null);

You can invoke Builder that will distinguish mandatory params from optional ones:

Type obj = new Type.Builder(param1, param2).setParam6(param6).build();

Here just param1 and param2 are mandatory, the rest is optional.

Advantages:
– the code is easier to read and more robust
– good way to cope with many optional construcotr parameters

Effective Java

Effective Java (Joshua Bloch) is a book with advanced Java programming techniques that make Java code more robust and readable. I am currently reading it and this is why these [Effective Java] posts come up here. These are summaries of chapters that are most valuable in my opinion.

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!





Object construction: static factory method instead of constructor [Effective Java]

14 09 2013

What is it

Static factory method is a public static method that is used to create object – exactly the same as constructor. So when it is better than usual constructor?

Advantages

– unlike constructors, they have names, so you can easily distinguish and know what kind of object they actually build

– unlike constructors, they do not have to create new instance each time they are called, so in other words you can easily make this class a singleton

– they can return an object of any subtype of their return type

– they reduce verbosity of creating parameterized type instances. So instead of header:

public Bread(boolean old);

you can use

public static Bread createOldBread();

and

public static Bread createFreshBread();

Disadvantages

– A class without public or protected constructors can’t be subclassed

– static factory methods are not easily distinguishable from any other static methods, so good naming is required

Effective Java

Effective Java (Joshua Bloch) is a book with advanced Java programming techniques that make Java code more robust and readable. I am currently reading it and this is why these [Effective Java] posts come up here. These are summaries of chapters that are most valuable in my opinion.

Did I help you?
I manage this blog and share my knowledge for free sacrificing my time. If you appreciate it and find this information helpful, please consider making a donation in order to keep this page alive and improve quality

Donate Button with Credit Cards

Thank You!








%d bloggers like this: