Thursday, May 3, 2012

SoftReference Cache

This blog is about creating a SoftReference Cache for Java. I created it to use it in my Android Applications, but it will probably work in any Java environment.

SoftReference

What is a SoftReference? A SoftReference is a java class that represents a reference that me be deleted by the Garbage Collector (GC).

What does this mean? Every object in Java has references to other objects. As long as a object has references to it, the GC will not delete the item. When the application runs out of memory and the GC is unable to free more memory by deleting items that has no real reference to it any more, the items with only SoftRefences to it will be deleted. So, basically the items that only have a SoftReference to it will be kept in memory as long as possible until there is no other way to free memory.

Because objects with SoftRefences to it will be kept in memory as long as possible they are perfect for implementing caches.

To create a SoftReference to a object, you can use the following:

SoftReference<String> ref = new SoftReference<String>("Hello world");

To retrieve the data:

String value = ref.get();

if (value == null) {
  // The reference is cleaned up by the Garbage Collector.
  // Initialize the object again.
}

// Use the value (from the SoftReference or from re-initializing.
.......

SoftReferenceCache

How can we create a cache that uses SoftReferences? We will do this with a HashMap and Java Generics.

First we start with a class called SoftReferenceCache that will get two generic parameters. One for the key's and one for the value's. In the constructor we will create the HashMap.

public class SoftReferenceCache<K, V> {
  private final HashMap<K, SoftReference<V>> mCache;

  public SoftReferenceCache() {
    mCache = new HashMap<K, SoftReference<V>>();
  }
}

To add new items to the cache, we will add a put function.

public void put(K key, V value) {
  mCache.put(key, new SoftReference<V>(value));
}


You see that the SoftReference is automaticly created inside the put function and that the types are used that you give the SoftReferenceCache during construction.

To retrieve the value's from the SoftRefenceCache you have to implement a get function.

public V get(K key) {
  V value = null;

  SoftReference<V> reference = mCache.get(key);

  if (reference != null) {
    value = reference.get();
  }

  return value;
}

This function will check if the reference exist and return it's value. The user of the SoftReferenceCache should still check if the returnvalue isn't null. That can happen if the Garbage Collector has removed the object from memory.

Here is a example of how to use this class.

SoftReferenceCache<Integer, Person> mPersonCache = new SoftReferenceCache<Integer, Person>();

mPersonCache.put(0, new Person("Peter");
mPersonCache.put(1, new Person("Jan");
mPersonCahce.put(2, new Person("Kees");

Person p = (Person)mPersonCache.get(1); // This will retrieve the Person object of Jan.

Below if the full listing of the SoftReferenceCache

package com.peerke.cache;

import java.lang.ref.SoftReference;
import java.util.HashMap;

/**
 * SoftRefenceCache
 * @param <K> The type of the key's.
 * @param <V> The type of the value's.
 */
public class SoftReferenceCache<K, V> {
  private final HashMap<K, SoftReference<V>> mCache;

  public SoftReferenceCache() {
    mCache = new HashMap<K, SoftReference<V>>();
  }

  /**
   * Put a new item in the cache. This item can be gone after a GC run.
   * 
   * @param key
   *            The key of the value.
   * @param value
   *            The value to store.
   */
  public void put(K key, V value) {
    mCache.put(key, new SoftReference<V>(value));
  }

  /**
   * Retrieve a value from the cache (if available).
   * 
   * @param key
   *            The key to look for.
   * @return The value if it's found. Return null if the key-value pair is not
   *         stored yet or the GC has removed the value from memory.
   */
  public V get(K key) {
    V value = null;

    SoftReference<V> reference = mCache.get(key);

    if (reference != null) {
      value = reference.get();
    }

    return value;
  }
}

Read more »

Tuesday, February 28, 2012

Fragments

In my first technical blog item I want to talk about Android Fragments. What are Android Fragments and what are they used for? And how can it help me building my Android application? This will all be discussed in this article.

First you have to know what an activity is. An activity is a single UI screen in a Android application. Every Android application consist of one or multiple activity's. Switching between screens happens by switching between activity's. Visible items on the activity's are called view's. 

What is a Fragment?

In Android 3.0 (and above) you have the ability to use fragments. So, what are those fragments? A Fragment is a partial of the screen (or fullscreen) that has it own life cycle. It recieves it own input events and can be reused on multiple activity's. You can also use multiple Fragments inside one activity.

An example how you use fragments inside in an activity can be seen in the picture below:


In the example above you see two fragments. The green fragment is a list and the blue fragment shows the details of a list item. You see how can use the Fragment to differ the UI on tablets and phones.

How to create a Fragment?

You can create a fragment by creating a new class and extending the Fragment class. In this new class you have to override the onCreateView function. This function is part of the Fragment life cycle and is called to create a View. When you add the Fragment to the activity this View will be displayed. The View can be a normal view (like a ImageView, TextView, etc.), but it can also be a ViewGroup for the more complex layouts. You already have a LayoutInflater, so inflating from xml is easy. 

package com.example;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, 
                           Bundle savedInstanceState) {
    return inflater.inflate(R.layout.mylayout, null);
  }
}
In this example you see that the layout called mylayout is inflated and returned as view.

Include a Fragment in your Activity

You can include an Fragment into an Activity from xml layout (with some limitations) or from Java code.

To use your Fragment from a xml layout create a layout like the example below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.MyFragment"
            android:id="@+id/list"
            android:layout_width="match_parent"            android:layout_height="match_parent" />
</LinearLayout>


The name parameter referred to the Fragment that you have created. If you show this layout in your application and view this in the Hierarchy Viewer (part of DDMS in Eclipse), you will see that there is no trace of the Fragment itself. The Fragment part is replaced by the view that the onCreateView function is returning.

Another way is to add the Fragment from code with the FragmentManager. To do this you need a layout with a ViewGroup in it. A LinearLayout for example. This will be the container ViewGroup where the fragment will be placed in. Don't forget to give it a id.


@Override
public View addFragment(Fragment aFragment) { FragmentManager fragmentManager = getFragmentManager() FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.fragment_container, aFragment); fragmentTransaction.commit(); }
In this example you see a function that will add the given Fragment to the layout. It will be played inside the ViewGroup with the id fragment_container. The Fragment manager is needed to get a FragmentTransaction object. In this FragmentTransaction object you can do one or multiple changes to the Fragments on the Activity. 

This is it. If you have any questions you can ask them below and I will try to answer that as good as possible. Good luck coding your Fragments.



Read more »

Wednesday, February 15, 2012

Starting a blog

This is my first blog item ever. I always thought blogging wasn't for me, but I would like to give it a try. I just want to see if people would like to read it (or not?).

So who am I? I'm Peerke. I'm a Software Developer that specializes in Android development. So a lot of the topics I'm going to blog about will be about Android and developing for Android.

This is it for now. Stay tuned to my blog!
Read more »