Quantcast
Viewing latest article 4
Browse Latest Browse All 10

Custom Annotation in Android

For definition of java annotation i can’t think a better definition than wikipedia “An annotation, in the Java computer programming language, is a special form of syntactic metadata that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Unlike Javadoc tags, Java annotations can be reflective in that they can be embedded in class files generated by the compiler and may be retained by the Java VM to be made retrievable at run-time.” http://en.wikipedia.org/wiki/Java_annotation Some of  the java programmers use annotations without even know about annotations. When ever you override any method of super class in you class, eclipse automatically adds the @override annotation above method name.

e.g.

@Override
    public String toString() {
    	return super.toString();
    }

In the above example code,
@Override: gives the information that toString() method is overridden from Object class.
In this post we will create custom annotations.

1. First we will create a custom annotation for Database table name.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DatabaseTable {

	String tableName();
}

Explanation of above code:
@interface: We can see in the above code is similar to interface declaration. @Retention(RetentionPolicy.RUNTIME): We need this annotation type at runtime. We are using RetentionPolicy.RUNTIME.
@Target(ElementType.TYPE): Indicates that this annotation type will be used to annotate class declaration

2. Next we will create another annotation for column names.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DatabaseField {

	String columnName() default "";
	String columnType();
	boolean canBeNull() default true;

}

Explanation of above code:
@Target(ElementType.FIELD): Indicates that this annotation type will used to annotate fields declarations.
default: is used to assign default value.

3. We will create UserInfo class that we want to save in database.

@DatabaseTable (tableName = "user")
public class UserData {

	@DatabaseField (columnName = "first_name", columnType ="TEXT")
	private String firstName;
	@DatabaseField (columnName = "last_name", columnType ="TEXT")
	private String lastName;
	@DatabaseField (columnName = "age", columnType ="INTEGER")
	private int age;

}

4. Create query for create table.

public String createTableQuery(Class clazz){
		DatabaseTable annot = (DatabaseTable) clazz.getAnnotation(DatabaseTable.class);
		String table = annot.tableName();
		Field[] fields = clazz.getDeclaredFields();
		StringBuilder sb = new StringBuilder("CREATE TABLE ").append(table).append(
						" (_id integer primary key");
				for (Field field : fields) {
					DatabaseField fieldAnnot = (DatabaseField) field.getAnnotation(DatabaseField.class);
					String columnName = fieldAnnot.columnName();
					String columnType = fieldAnnot.columnType();
					sb.append(", ").append(columnName).append(" ").append(columnType);
				}
				sb.append(")");
				return sb.toString();
		}

5. We will call this method like this

String sqlQuery = createTableQuery(UserInfo.Class);

Complete implementation of ORM(object relational mapping) is complex. You can check OrmLite – Lightweight Object Relational Mapping (ORM) Java Package for complete annotation based ORM implementation.

We can also search at run time about annotated classes.

public static List getModels(Context context, String packageName)
			throws IOException, URISyntaxException, ClassNotFoundException,
			NameNotFoundException {

		String apkName = context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir;
		DexFile dexFile = new DexFile(apkName);
		PathClassLoader pathLoader = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader());
		DexClassLoader classLoader = new DexClassLoader(apkName,
				new ContextWrapper(context).getCacheDir().getAbsolutePath(),
				null, pathLoader);
		List classes = new ArrayList();
		Enumeration entries = dexFile.entries();

		while (entries.hasMoreElements()) {

			String entry = (String) entries.nextElement();

			if (entry.startsWith(packageName)) {
				Class entryClass = classLoader.loadClass(entry);
				if (entryClass != null) {
					Annotation[] annotations = entryClass.getAnnotations();
					for (Annotation annotation : annotations) {
						if (annotation instanceof DatabaseTable) {
							classes.add(entryClass);
						}
					}
				}
			}
		}

		return classes;
	}

This was a small example of custom annotation. We can use custom annotations in a lots of ways like configuration, unit testing, etc.

Incoming search terms:


Viewing latest article 4
Browse Latest Browse All 10

Trending Articles