Android Rules

These rules deal with the Android SDK, mostly related to best practices. To get better results, make sure that the auxclasspath is defined for type resolution to work.

CallSuperFirst

Since: PMD 4.2.5

Super should be called at the start of the method

This rule is defined by the following XPath expression:

//MethodDeclaration[MethodDeclarator[
  @Image='onCreate' or
  @Image='onConfigurationChanged' or
  @Image='onPostCreate' or
  @Image='onPostResume' or
  @Image='onRestart' or
  @Image='onRestoreInstanceState' or
  @Image='onResume' or
  @Image='onStart'
  ]]
    /Block[not(
      (BlockStatement[1]/Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image= ancestor::MethodDeclaration/MethodDeclarator/@Image]) or
      ((BlockStatement[1]/Statement/IfStatement/Expression[
  PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGD' or @Image='Config.LOGV']
  or
  ConditionalAndExpression/PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGD' or @Image='Config.LOGV']
         ]) and
      (BlockStatement[2]/Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image= ancestor::MethodDeclaration/MethodDeclarator/@Image])))]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[
  typeof(@Image, 'android.app.Activity', 'Activity') or
  typeof(@Image, 'android.app.Application', 'Application') or
  typeof(@Image, 'android.app.Service', 'Service')
]]]

        

Example:

                
   public class DummyActivity extends Activity {
    public void onCreate(Bundle bundle) {
     // missing call to super.onCreate(bundle)
     foo();
    }
   }

    
            

CallSuperLast

Since: PMD 4.2.5

Super should be called at the end of the method

This rule is defined by the following XPath expression:

          
//MethodDeclaration[MethodDeclarator[
  @Image='finish' or
  @Image='onDestroy' or
  @Image='onPause' or
  @Image='onSaveInstanceState' or
  @Image='onStop' or
  @Image='onTerminate'
  ]]
   /Block/BlockStatement[last()]
    [not(Statement/StatementExpression/PrimaryExpression/PrimaryPrefix[@Image= ancestor::MethodDeclaration/MethodDeclarator/@Image])]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[
  typeof(@Image, 'android.app.Activity', 'Activity') or
  typeof(@Image, 'android.app.Application', 'Application') or
  typeof(@Image, 'android.app.Service', 'Service')
]]]

        

Example:

                
      
   public class DummyActivity extends Activity {
    public void onPause() {
     foo();
     // missing call to super.onPause()
    }
   }

    
            

ProtectLogD

Since: PMD 4.2.5

Log.d calls should be protected by checking Config.LOGD first

This rule is defined by the following XPath expression:

          
//PrimaryPrefix/Name[@Image='Log.d']
[not(ancestor::IfStatement/Expression[
  PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGD']
  or
  ConditionalAndExpression/PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGD']
])]

        

Example:

                
      
   public class DummyActivity extends Activity {
    public void foo() {
     Log.d("TAG", "msg1"); // Bad

     bar();

     if (Config.LOGD) Log.d("TAG", "msg1"); // Good
    }
   }

    
            

ProtectLogV

Since: PMD 4.2.5

Log.v calls should be protected by checking Config.LOGV first

This rule is defined by the following XPath expression:

          
//PrimaryPrefix/Name[@Image='Log.v']
[not(ancestor::IfStatement/Expression[
  PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGV']
  or
  ConditionalAndExpression/PrimaryExpression/PrimaryPrefix/Name[@Image='Config.LOGV']
])]

        

Example:

                
      
   public class DummyActivity extends Activity {
    public void foo() {
     Log.v("TAG", "msg1"); // Bad

     bar();

     if (Config.LOGV) Log.v("TAG", "msg1"); // Good
    }

    
            

DoNotHardCodeSDCard

Since: PMD 4.2.6

Use Environment.getExternalStorageDirectory() instead of "/sdcard"

This rule is defined by the following XPath expression:

//Literal[starts-with(@Image,'"/sdcard')]

Example:

                
      
public class MyActivity extends Activity {
  protected void foo() {
    String storageLocation = "/sdcard/mypackage"; // BAD

    storageLocation = Environment.getExternalStorageDirectory() + "/mypackage"; // GOOD
  }
}