Friday, June 24, 2011

Native Methods and Libraries - Java

What are Native Methods and Libraries?
Native methods and native libraries are bits of platform-specific executable code (written in languages such as C or C++) contained in libraries or DLLs. Inside your Java applications you can gain access to the functions inside those libraries, allowing you to create a sort of hybrid Java and native code application. Although using native methods can give you some extra benefits Java does not provide (such as faster execution or access to a large body of existing code), there are significant disadvantages in using native methods as well.

Why Use Native Methods?
  • Gaining access to special capabilities of your computer or operating system
  • Needing the extra speed that native methods provide
  • Needing access to a large body of existing code
Disadvantages of Native Methods

With a hybrid Java and native method program, however, you've given up that cross-platform capability. First of all, Java programs that use native methods cannot be applets. Period. For security reasons, applets cannot load native code. So if you use native methods, you've just removed the enormous number of users on the World Wide Web from your market.

Native code is, by definition, platform specific. The native code must exist on the platform your Java program is running on for that program to work. For your program to work on different platforms, you'll have to port your native code to that specific platform-which may not be a trivial task. And as new systems or new versions of operating systems appear, you may have to update or re-release new versions of that native code for every system. The write-it-once-run-it-everywhere advantage of Java ceases to exist when you use native methods.

Just-in-Time Compilers

Just-in-time compilers translate Java bytecode into native machine code on-the-fly as the bytecode is running. Depending on how good the JIT compiler is, you can often get very close to native execution speeds out of a standard Java program-without needing to use native code and without needing to make any modifications to your Java program-it just works.
The disadvantage, however, is that to get the speed increase your Java program must be run on a platform that has a JIT compiler installed. 

Writing Native Methods

In this section you'll learn the steps you must take to write your Java code so that it uses native methods, This involves four basic steps:
  • Write your Java code so that the methods that will be native have special declarations using the native modifier.
  • Compile your Java code and use the javah program to generate special header and stub files, which make up the starting point for your native code.
  • Write your native implementations of the native methods.
  • Compile all the native files into a shared library or DLL and run your Java program.
Write Your Java Code

The first step to implementing native methods is to decide which methods in which classes of your Java program will be native.
To declare that a method will be native inside your Java code, you add the native modifier to that method signature, like this:
public native void goNative(int x, int y);
 Note also that the native method in your Java code has no method body. Because this is a native method, its implementation will be provided by the native code, not by Java. Just add a semicolon to the end of the line.

The other change you'll have to make to your Java code is to explicitly load the native library that will contain the native code for these methods. To do this, you add the following boilerplate code to your Java class:
static {
This bit of code, called a static initializer, is used to run code only once when the class is first loaded into the system.The static initializer executes theSystem.loadLibrary() method to load in your native library as the class itself is being loaded. If the native library fails to load for some reason, the loading of the Java class fails as well, guaranteeing that no half-set-up version of the class can ever be created.
You can pick any name you want for your native library-here we've used the UNIX convention that libraries start with the word lib and end with the extension .so. For Windows systems, libraries typically end with the extension .DLL.
You can also use the System.load() method to load your native libraries. The difference is that the single argument to load() is the complete pathname to your native library, whereas the argument to loadLibrary() is just the library name.
And that's all you need to do in your Java code to create native methods and libraries. Subclasses of any class containing your new native methods can still override them, and these new (Java) methods are called for instances of the new subclasses (just as you'd expect).
Listing 1 shows an example of a Java program called SimpleFile that was written to use native methods. This program might be used in a version of the Java environment that does not provide file input or output (I/O). Because file I/O is typically system-dependent, native methods must be used to implement those operations.

Listing 1. SimpleFile, a Java program that uses native methods.
1: public class  SimpleFile {
 2:     public static final  char    separatorChar = '>';
 3:     protected    String  path;
 4:     protected    int     fd;
 6:     public  SimpleFile(String s) {
 7:         path = s;
 8:     }
10:     public String  getFileName() {
11:         int  index = path.lastIndexOf(separatorChar);
13:         return (index < 0) ? path : path.substring(index + 1);
14:     }
16:     public String  getPath() {
17:         return path;
18:     }
20:     public native boolean  open();
21:     public native void     close();
22:     public native int      read(byte[]  buffer, int  length);
23:     public native int      write(byte[]  buffer, int  length);
25:     static {
26:         System.loadLibrary("simple");  // runs when class first loaded
27:     }
28: }

The first thing you notice about SimpleFile's implementation is how unremarkable the first two-thirds of its Java code is! It looks just like any other class, with a class and an instance variable, a constructor, and two normal method implementations (getFileName() and getPath()). Then, in lines 20 through 23, there are four native method declarations, which are just normal method declarations with the code block replaced by a semicolon and the modifier native added. These are the methods you have to implement in C code later.
Finally, note the call to System.loadLibrary() in line 26, which loads a native library called simple. (We've intentionally violated library-naming standards here to make this example simpler.)

The unusual separatorChar ('>') is used simply to demonstrate what an implementation might look like on some strange computer whose file system didn't use any of the more common path-separator conventions. 

After you write the native part of your Java program, SimpleFile objects can be created and used in the usual way:
SimpleFile  f = new SimpleFile(">some>path>and>fileName");;;
Generate Header and Stub Files

The second step to implementing native code is to generate a special set of header and stub files for use by your C or C++ files that implement those native methods. To generate these header and stub files, you use the javah program, which is part of the JDK (it's called JavaH in the Mac JDK).
First, you'll need to compile your Java program as you would any other Java program, using the Java compiler.

Header Files

To generate header files for a class, use the javah program with the name of the class file, minus the .class extension. For example, to generate the header file for the SimpleFile class, use this command line:
javah SimpleFile
To generate the header file for the SimpleFile class, drag-and-drop the class file onto the JavaH icon.
The file SimpleFile.h will be created in the same directory as the SimpleFile.class file.
Note that if the class you've given to javah is inside a package, javah prepends the package's full name to the header filename (and to the structure names it generates inside that file) with all the dots (.) replaced by underscores (_). If SimpleFile had been contained in a hypothetical package calledacme.widgets.filesjavah would have generated a header file named acme_widgets_files_SimpleFile.h, and the various names within it would have been renamed in a similar manner.

Listing 2 shows the header file that is generated by javah.

Listing 2. SimpleFile.h (a header file).
1: #include <native.h>
 2: /* Header for class SimpleFile */
 4: #ifndef _Included_SimpleFile
 5: #define _Included_SimpleFile
 6: struct Hjava_lang_String;
 8: typedef struct ClassSimpleFile {
 9: #define SimpleFile_separatorChar 62L
10:     struct Hjava_lang_String *path;
11:     long fd;
12: } ClassSimpleFile;
13: HandleTo(SimpleFile);
15: #ifdef __cplusplus
16: extern "C" {
17: #endif
18: extern /*boolean*/ long SimpleFile_open(struct HSimpleFile *);
19: extern void SimpleFile_close(struct HSimpleFile *);
20: extern long SimpleFile_read(struct HSimpleFile *,HArrayOfByte *,long);
21: extern long SimpleFile_write(struct HSimpleFile *,HArrayOfByte *,long);
22: #ifdef __cplusplus
23: }
24: #endif
25: #endif

There are a few things to note about this header file. First, note the struct ClassSimpleFile, which contains variables that parallel the instance variables inside your class. Second, note the method signatures at the end of the file; these are the function definitions you'll use in your C or C++ file to implement the actual native methods in the Java code.

Stub Files

To "run interference" between the Java world of objects, arrays, and other high-level constructs and the lower-level world of C, you need stubs, which translate arguments and return values between Java and C.
Stubs are pieces of "glue" code that tie together Java and C. Stubs translate arguments and values and convert the various constructs in each language to something that can be understood in the other.
Stubs can be automatically generated by javah, just like headers. There isn't much you need to know about the stub file, just that it has to be compiled and linked with the C code you write to allow it to interface properly with Java.
To create stub files, you also use the javah program:
Use the javah program with the -stubs option to create the stub file:
javah -stubs SimpleFile
The file SimpleFile.c will be generated in the same directory as the class file.

Listing 3 shows the result of the stub file for the SimpleFile class.

Listing 3. SimpleFile.c (a stub file).
1:/* DO NOT EDIT THIS FILE - it is machine generated */
 2:#include <StubPreamble.h>
 4:/* Stubs for class SimpleFile */
 5:/* SYMBOL: "SimpleFile/open()Z", Java_SimpleFile_open_stub */
 6:__declspec(dllexport) stack_item *Java_SimpleFile_open_stub(stack_item *_P_,
 7:    struct execenv *_EE_) {
 8:        extern long SimpleFile_open(void *);
 9:        _P_[0].i = (SimpleFile_open(_P_[0].p) ? TRUE : FALSE);
10:        return _P_ + 1;
12:/* SYMBOL: "SimpleFile/close()V", Java_SimpleFile_close_stub */
13:__declspec(dllexport) stack_item *Java_SimpleFile_close_stub(stack_item *_P_,
14:    struct execenv *_EE_) {
15:        extern void SimpleFile_close(void *);
16:        (void) SimpleFile_close(_P_[0].p);
17:        return _P_;
19:/* SYMBOL: "SimpleFile/read([BI)I", Java_SimpleFile_read_stub */
20:__declspec(dllexport) stack_item *Java_SimpleFile_read_stub(stack_item *_P_,
21:    struct execenv *_EE_) {
22:        extern long SimpleFile_read(void *,void *,long);
23:        _P_[0].i = SimpleFile_read(_P_[0].p,((_P_[1].p)),((_P_[2].i)));
24:        return _P_ + 1;
26:/* SYMBOL: "SimpleFile/write([BI)I", Java_SimpleFile_write_stub */
27:__declspec(dllexport) stack_item *Java_SimpleFile_write_stub(stack_item *_P_,
28:    struct execenv *_EE_) {
29:        extern long SimpleFile_write(void *,void *,long);
30:        _P_[0].i = SimpleFile_write(_P_[0].p,((_P_[1].p)),((_P_[2].i)));
31:        return _P_ + 1;

Implementing the Native Library

The last step, and the most difficult, is to write the C code for your native methods.
The header file generated by javah gives you the prototypes of the functions you need to implement to make your native code complete. You then write some C code that implements those functions and provides the native facilities that your Java class needs (in the case of SimpleFile, some low-level file I/O routines).
You'll want to include your header file as part of the initial includes for your native implementation:
#include <SimpleFile.h>

Listing 4 shows the native implementation of the methods from the SimpleFile class.

Listing 4. SimpleFileNative.c, a C implementation of a native method from SimpleFile
1: #include "SimpleFile.h"     /* for unhand(), among other things */
 3: #include <sys/param.h>      /* for MAXPATHLEN */ 
 4: #include <fcntl.h>          /* for O_RDWR and O_CREAT */
 6: #define LOCAL_PATH_SEPARATOR  '/'    /* UNIX */
 8: static void  fixSeparators(char *p) { 
 9:     for (;  *p != '\0';  ++p)
10:         if (*p == SimpleFile_separatorChar) 
11:             *p = LOCAL_PATH_SEPARATOR;
12: }
14: long  SimpleFile_open(struct HSimpleFile  *this) { 
15:     int   fd;
16:     char  buffer[MAXPATHLEN];
18:     javaString2CString(unhand(this)->path, buffer, sizeof(buffer)); 
19:     fixSeparators(buffer);
20:     if ((fd = open(buffer, O_RDWR | O_CREAT, 0664)) < 0)    /* UNIX open */
21:         return(FALSE);   /* or, SignalError() could "throw" an exception */
22:     unhand(this)->fd = fd;         /* save fd in the Java world */ 
23:     return(TRUE);
24: }
26: void  SimpleFile_close(struct HSimpleFile  *this) { 
27:     close(unhand(this)->fd);
28:     unhand(this)->fd = -1;
29: }
31: long  SimpleFile_read(struct HSimpleFile  *this, 
32:     HArrayOfByte  *buffer, _ long  count) {
33:     char  *data     = unhand(buffer)->body;  /* get array data   */ 
34:     int    len      = obj_length(buffer);    /* get array length */ 
35:     int    numBytes = (len < count ? len : count);
37:     if ((numBytes = read(unhand(this)->fd, data, numBytes)) == 0) 
38:         return(-1);
39:     return(numBytes);       /* the number of bytes actually read */ 
40: }
42: long  SimpleFile_write(struct HSimpleFile  *this, 
43:     HArrayOfByte  *buffer,_ long  count) {
44:     char  *data = unhand(buffer)->body; 
45:     int    len  = obj_length(buffer);
47:     return(write(unhand(this)->fd, data, (len < count ? len : count))); 
48: }

Compile Everything into a Shared Library

The final step is to compile all the .c files, including the stub file and your native method files. Use your favorite C compiler to compile and link those two files into a shared library (a DLL on Windows). On some systems, you may need to specify special compilation flags that mean "make it relocatable and dynamically linkable." (Those flags, if they are required, may vary from system to system; check with your compiler documentation for details.)

If you have several classes with native methods, you can include all their stubs in the same .c file, if you like. Of course you might want to name it something else, such as Stubs.c, in that case.

The resulting library should be the same name as you gave in your original Java class file as the argument to System.loadLibrary(). In the SimpleFile class, that library was called You'll want to name the library that same name and install it wherever your particular system needs libraries to be installed.

Using Your Library

With all the code written and compiled and installed in the right place, all you have to do is run your Java program using the Java bytecode interpreter. When the Java class is loaded, it will also try to load the native library automatically; if it succeeds you should be able to use the classes in your Java class, and they will transparently run the native libraries as they are needed.
If you get an error that the library was not found, the most likely problem is that you do not have your environment set up correctly or that you have not installed your library in the right place.
DLL files are located according to the standard Windows algorithm: the directory the application was located in, the current directory, the System directory in Windows 95 (System32 in NT), the System directory in NT, the Windows directory, and then directories listed in the PATH environment variable.
UNIX systems use the environment variable LD_LIBRARY_PATH to search for libraries. This environment variable should include the standard places shared libraries are stored, as well as the current directory (.). After LD_LIBRARY_PATH has been set, Java will be able to find your library.
Shared libraries for Java must be stored in the folder System Folder: Extensions:JavaSoft Folder. Rather than copying your native library there, you can also just create an alias to your native library and put it in that folder.

Friday, June 10, 2011

Android Cloud to Device Messaging(C2DM):Project

Android Push application is an Android Application which is registers to the C2DM Server.It allows user to send and store contact,message,images,maps from the Server to your Device.
It uses a features Cloud to Device Messaging to deliver messages that actually pushes the messages to your device, therefore it saves much more battery and best of all,there is nothing you need to do to enable it.

The entire project(Android Cloud to Device Messaging) is mainly divided into three parts i,e the primary processes involves in this project are

     -Android Push Application
     - Cloud to Device Messaging framework.
     - Android Push server thats sends message via C2DM Server.

Overview of LifeCycle:

Check following URL too to know more about C2DM,Authorization Token And Third Party Application Server.

Some Screenshot:


You will get Notification when there is a new message

If the push data are Map,Image or Number,it will open on your device according to that

Thursday, June 9, 2011

Android Code Style

Android follow standard Java coding conventions. We add a few rules:
  1. Exceptions: Never catch and ignore them without explanation.
  2. Exceptions: do not catch generic Exception, except in library code at the root of the stack.
  3. Finalizers: generally don't use them.
  4. Imports: Fully qualify imports.

1.Exceptions: do not ignore:

Never do this.Never write code that completely ignores an exception like this:

void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) { }

  • Throw the exception up to the caller of your method.
void setServerPort(String value) throws NumberFormatException {
    serverPort = Integer.parseInt(value);  }
  • Throw a new exception that's appropriate to your level of abstraction.
void setServerPort(String value) throws ConfigurationException {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        throw new ConfigurationException("Port " + value + " is not valid.");
Handle the error gracefully and substitute an appropriate value in the catch {} block.

/** Set port. If value is not a valid number, 80 is substituted. */
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        serverPort = 80;  // default port for server 
If you are confident that actually ignoring the exception is appropriate then you may ignore it, but you must also comment why with a good reason:

/** If value is not a valid number, original port number is used. */
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        // Method is documented to just ignore invalid user input.
        // serverPort will just be unchanged.

2.Don't Use Finalizers

3.Fully Qualify Imports
There are two possible ways to import it:
  1. import foo.*;
  2. import*;
2 reduces the number of import statements.It makes code more readable for maintainers.
Every file should have a copyright statement at the top. Then a package statement and import statements should follow, each block separated by a blank line. And then there is the class or interface declaration. In the Javadoc comments, describe what the class or interface does.
 * Copyright (C) 2010 The Android Open Source Project 


import android.os.Blah;
import android.view.Yada;

import java.sql.ResultSet;
import java.sql.SQLException;

 * Does X and Y and provides an abstraction for Z.
public class Foo {
Every class and nontrivial public method you write must contain a Javadoc comment with at least one sentence describing what the class or method does. This sentence should start with a 3rd person descriptive verb. Examples:

/** Returns the correctly rounded positive square root of a double value. */
static double sqrt(double a) {

 * Constructs a new String by converting the specified array of 
 * bytes using the platform's default character encoding.
public String(byte[] bytes) {
Every method you write, whether public or otherwise, would benefit from Javadoc. Public methods are part of an API and therefore require Javadoc.

Short methods
To the extent that it is feasible, methods should be kept small and focused. It is, however, recognized that long methods are sometimes appropriate, so no hard limit is placed on method length. If a method exceeds 40 lines or so, think about whether it can be broken up without harming the structure of the program.
Define Fields in Standard Places
Fields should be defined either at the top of the file, or immediately before the methods that use them.

Local variables

The scope of local variables should be kept to a minimum (Effective Java Item 29). By doing so, you increase the readability and maintainability of your code and reduce the likelihood of error. Each variable should be declared in the innermost block that encloses all uses of the variable.
Local variables should be declared at the point they are first used. Nearly every local variable declaration should contain an initializer. If you don't yet have enough information to initialize a variable sensibly, you should postpone the declaration until you do.
One exception to this rule concerns try-catch statements. If a variable is initialized with the return value of a method that throws a checked exception, it must be initialized inside a try block. If the value must be used outside of the try block, then it must be declared before the try block, where it cannot yet be sensibly initialized:
// Instantiate class cl, which represents some sort of Set 
Set s = null;
try {
    s = (Set) cl.newInstance();
} catch(IllegalAccessException e) {
    throw new IllegalArgumentException(cl + " not accessible");
} catch(InstantiationException e) {
    throw new IllegalArgumentException(cl + " not instantiable");

// Exercise the set 
But even this case can be avoided by encapsulating the try-catch block in a method:
Set createSet(Class cl) {
    // Instantiate class cl, which represents some sort of Set 
    try {
        return (Set) cl.newInstance();
    } catch(IllegalAccessException e) {
        throw new IllegalArgumentException(cl + " not accessible");
    } catch(InstantiationException e) {
        throw new IllegalArgumentException(cl + " not instantiable");


// Exercise the set 
Set s = createSet(cl);
Loop variables should be declared in the for statement itself unless there is a compelling reason to do otherwise:
for (int i = 0; i n; i++) {

for (Iterator i = c.iterator(); i.hasNext(); ) {


The ordering of import statements is:
  1. Android imports
  2. Imports from third parties (com, junit, net, org)
  3. java and javax
To exactly match the IDE settings, the imports should be:
  • Alphabetical within each grouping.
  • Capital letters are considered to come before lower case letter (e.g. Z before a).
  • There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).


Originally there was no style requirement on the ordering. This meant that the IDE's were either always changing the ordering, or IDE developers had to disable the automatic import management features and maintain the imports by hand. This was deemed bad. When java-style was asked, the preferred styles were all over the map. It pretty much came down to our needing to "pick an ordering and be consistent." So we chose a style, updated the style guide, and made the IDEs obey it. We expect that as IDE users work on the code, the imports in all of the packages will end up matching this pattern without any extra engineering effort.
The style chosen such that:
  • The imports people want to look at first tend to be at the top (android)
  • The imports people want to look at least tend to be at the bottom (java)
  • Humans can easily follow the style
  • The IDE's can follow the style

What about static imports?

The use and location of static imports have been mildly controversial issues. Some people would prefer static imports to be interspersed with the remaining imports, some would prefer them reside above or below all other imports. Additinally, we have not yet come up with a way to make all IDEs use the same ordering.
Since most people consider this a low priority issue, just use your judgement and please be consistent.


We use 4 space indents for blocks. We never use tabs. When in doubt, be consistent with code around you.
We use 8 space indents for line wraps, including function calls and assignments. For example, this is correct:
Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);
and this is not correct:
Instrument i =
    someLongExpression(that, wouldNotFit, on, one, line);

Field Names

  • Non-public, non-static field names start with m.
  • Static field names start with s.
  • Other fields start with a lower case letter.
  • Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;


class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
We require braces around the statements for a conditional. Except, if the entire conditional (the condition and the body) fit on one line, you may (but are not obligated to) put it all on one line. That is, this is legal:

if (condition) {
    body(); // ok 
if (condition) body(); // ok
but this is still illegal:
if (condition)
    body(); // bad

Line length

Each line of text in your code should be at most 100 characters long.
There has been lots of discussion about this rule and the decision remains that 100 characters is the maximum.
Exception: if a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters for ease of cut and paste.
Exception: import lines can go over the limit because humans rarely see them. This also simplifies tool writing.

Java 1.5 Annotations

Annotations should precede other modifiers for the same language element. Simple marker annotations (e.g. @Override) can be listed on the same line with the language element. If there are multiple annotations, or parameterized annotations, they should each be listed one-per-line in alphabetical order.
Android -standard practices for the three predefined annotations in Java 1.5's are:


The @Deprecated annotation must be used whenever the use of the annotated element is discouraged. If you use the @Deprecated annotation, you must also have a @deprecated Javadoc tag and it should name an alternate implementation. In addition, remember that a @Deprecated method is still supposed to work.
If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation.


The @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class.
For example, if you use the @inheritdocs Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class's method.


The @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this "impossible to eliminate" test, the @SuppressWarnings annotation must be used, so as to ensure that all warnings reflect actual problems in the code.
When a @SuppressWarnings annotation is necessary, it must be prefixed with a TODO comment that explains the "impossible to eliminate" condition. This will normally identify an offending class that has an awkward interface. For example:
// TODO: The third-party class com.third.useful.Utility.rotate() needs generics 
List<String> blix = Utility.rotate(blax);
When a @SuppressWarnings annotation is required, the code should be refactored to isolate the software elements where the annotation applies.

TODO style

Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.
TODOs should include the string TODO in all caps, followed by a colon:
// TODO: Remove this code after the UrlTable2 has been checked in.

// TODO: Change this to use a flag instead of a constant.
f your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code after all production mixers understand protocol V7.").


Our parting thought: BE CONSISTENT. If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around their if clauses, you should too. If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too.
The point of having style guidelines is to have a common vocabulary of coding, so people can concentrate on what you're saying, rather than on how you're saying it. We present global style rules here so people know the vocabulary. But local style is also important. If code you add to a a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Try to avoid this.


While logging is necessary it has a significantly negative impact on performance and quickly loses its usefulness if it's not kept reasonably terse. The logging facilities provides five different levels of logging. Below are the different levels and when and how they should be used.
  • ERROR: This level of logging should be used when something fatal has happened, i.e. something that will have user-visible consequences and won't be recoverable without explicitly deleting some data, uninstalling applications, wiping the data partitions or reflashing the entire phone (or worse). This level is always logged. Issues that justify some logging at the ERROR level are typically good candidates to be reported to a statistics-gathering server.
  • WARNING: This level of logging should used when something serious and unexpected happened, i.e. something that will have user-visible consequences but is likely to be recoverable without data loss by performing some explicit action, ranging from waiting or restarting an app all the way to re-downloading a new version of an application or rebooting the device. This level is always logged. Issues that justify some logging at the WARNING level might also be considered for reporting to a statistics-gathering server.
  • INFORMATIVE: This level of logging should used be to note that something interesting to most people happened, i.e. when a situation is detected that is likely to have widespread impact, though isn't necessarily an error. Such a condition should only be logged by a module that reasonably believes that it is the most authoritative in that domain (to avoid duplicate logging by non-authoritative components). This level is always logged.
  • DEBUG: This level of logging should be used to further note what is happening on the device that could be relevant to investigate and debug unexpected behaviors. You should log only what is needed to gather enough information about what is going on about your component. If your debug logs are dominating the log then you probably should be using verbose logging. This level will be logged, even on release builds, and is required to be surrounded by an if (LOCAL_LOG) or if (LOCAL_LOGD) block, where LOCAL_LOG[D] is defined in your class or subcomponent, so that there can exist a possibility to disable all such logging. There must therefore be no active logic in an if (LOCAL_LOG) block. All the string building for the log also needs to be placed inside the if (LOCAL_LOG) block. The logging call should not be re-factored out into a method call if it is going to cause the string building to take place outside of the if (LOCAL_LOG) block. There is some code that still says if (localLOGV). This is considered acceptable as well, although the name is nonstandard.
  • VERBOSE: This level of logging should be used for everything else. This level will only be logged on debug builds and should be surrounded by if (LOCAL_LOGV) block (or equivalent) so that it can be compiled out by default. Any string building will be stripped out of release builds and needs to appear inside the if (LOCAL_LOGV) block.

Naming test methods

When naming test methods, you can use an underscore to seperate what is being tested from the specific case being tested. This style makes it easier to see exactly what cases are being tested.
testMethod_specificCase1 testMethod_specificCase2void testIsDistinguishable_protanopia() {
    ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)
    assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))
    assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))