Thursday, May 21, 2015

Starting an Activity from a BroadcastReceiver

The context we are getting from the onReceive method's parameter is not an Activity.

@Overridepublic void onReceive(Context context, Intent intent) {


If we want to start an Activity from here, the System will return an error:

context.startActivity(startActIntent);

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag exception - Android


Add a flag to the intent and things will work fine.

// must add flag FLAG_ACTIVITY_NEW_TASK if the context is not an Activity;startActIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


Monday, May 18, 2015

Power multiplier: combining the flexibility of interface and code-reusability of abstract class

Let's say we have an interface: ParentFace, which specifies 2 methods for parents to punish the child: either to spank them or to ground them. Any Parent class can implement this interface and implement these 2 methods.

However, considering this situation: all parents spank the child the same way and the implementation of this method doesn't need to be changed through out the program.

You might be thinking of instead of creating an interface, we can create an abstract class and write the spankChild() method as an concrete implementation while leaving the groundChild() as an abstract method for subclasses to implement.

While this approach does the trick here but it loses the flexibility of using an interface since one class can only inherit from one parent class while interfaces does not have this limitation.

1
2
3
4
public interface ParentFace {
 void spankChild();
 void groundChild();
}


The trick here is to create an abstract class that implements this interface as the following code snippet:



1
2
3
4
5
6
7
8
9
public abstract class StrictParent  implements ParentFace  {
 @Override
 public void spankChild() {
  System.out.println("Kick in the ass!"); 
 }

 @Override
 public abstract void groundChild();
}

The benefit of doing so is that we can re-use the code within the abstract class StrickParent while taking advantages of the flexibility of the interface ParentFace by passing the subclasses as the interface type.

Here comes my parent - MyParent, who always spank the child before grounding him :-(
We can refer MyParent Instance either as StrictParent type or ParentFace type since its parent class has implemented the ParentFace interface.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class MyParent extends StrictParent{

 @Override
 public void groundChild() {
  // Let's punish the child first before grounding him or her
  spankChild();
  
  System.out.println("Ground the child for 2 days!");
  
 }
}

Now it's time to test out our code. In the Main method, we define a showMessage method which takes a ParentFace type instance as the parameter.

This is all the magic of this technique: programming to the interface instead of the abstract class.

It shows that we can both pass in a subclass of StrictParent or an implementation of ParentFace.

Pretty Flexible, ha!


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Main {
 
 
 public static void showMessage(ParentFace parent){
  parent.spankChild();
  parent.groundChild();
 }

 public static void main(String[] args) {
  
  // declare the type as the interface so that you can mock the Object later
  ParentFace mum = new MyParent();
  showMessage(mum);
  
  // this time try to mock the MyParent 
  mum = new ParentFace() {
   
   @Override
   public void spankChild() {
    System.out.println("pat on the back.");
   }

   @Override
   public void groundChild() {
    
    System.out.println("suspend his allowance.");
   }
  };
  
  showMessage(mum);
  
 }

}

The output of this program is:


Kick in the ass!
Kick in the ass!
Ground the child for 2 days!
pat on the back.
suspend his allowance.







Wednesday, May 13, 2015

:app:dexDebug Error During Gradle Build

Error:Execution failed for task ':app:dexDebug'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java'' finished with non-zero exit value 2


This is caused by duplicated dex files in one of the jar file.

The error message in this case is:

com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/analytics/internal/Command$1;


It turned out that Google updated their google play service, which conflicts with the Google Analytic Service.

So I changed the build file from

dependencies {
    compile 'com.android.support:support-v4:22.1.1'    compile 'com.google.android.gms:play-services:+'    compile files('libs/acra-4.5.0.jar')
    compile files('libs/jackson-annotations-2.2.2.jar')
    compile files('libs/jackson-core-2.2.2.jar')
    compile files('libs/jackson-databind-2.2.2.jar')
    compile files('libs/libGoogleAnalyticsServices-3.01.jar')
    compile('org.simpleframework:simple-xml:2.7.1') {
        exclude group: 'stax', module: 'stax-api'        exclude group: 'xpp3', module: 'xpp3'    }

To

compile 'com.google.android.gms:play-services:6.5.87'
Problem solved!

Tuesday, May 12, 2015

Model-View-Presenter implementation in Android Development

I've written a simple example to demonstrate the implementation of MVP pattern in Android, here is the code

https://github.com/Ericliu001/AndroidSimpleMVP

which is inspired by this post:


http://philosophicalhacker.com/2015/05/08/how-to-make-our-android-apps-unit-testable-pt-2/

and Google's presentation:

https://www.youtube.com/watch?v=kilmaSRq49g





The goal is to move business logics out of Android Components such as Activity, Fragment, Service and place they in POJO java classes, which have no dependency on Android SDK, and these classes are called Presenters.

As a result, the Presenter classes are Unit Testable and less error prone.


The TestCase class MainActPresenterTest is included in the project to demonstrate how to test against the MainActPresenter class
There are 3 separate projects: one implemented in conventional way; one with MVP, one uses Eventbus as a part of MVP

Monday, May 11, 2015

Using interface to Mock Object in Java.

We have a parent class StrictParent that defines a method punishChild();
1
2
3
abstract public class StrictParent {
 abstract void punishChild();
}



Then we define an interface ParentFace that declares a method punishChild() with exactly the same method signature as the method defined in StrickParent class
1
2
3
public interface ParentFace {
 void punishChild();
}



Now we have a class MyParent that is subclassed from StrictParent and implements the ParentFace. Notice that because the parent class and the interface declare the same method so it only need to override the method once. 
1
2
3
4
5
6
7
8
public class MyParent extends StrictParent implements ParentFace {

 @Override
 public void punishChild() {
  System.out.println("Kick in the ass!"); 
 }

}


Let's test run our code.

The core idea here is that by defining an interface that declares methods the same as the parent class, you add a layer of abstraction. Instead of passing the parent class type in the method parameter, we can pass the interface now and it makes the code flexible. In the following example, we replace the variable mum with a mocked-up Object.

This technique is particularly useful in Unit Testing.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Main {
 
 
 public static void showMessage(ParentFace parent){
  parent.punishChild();
 }

 public static void main(String[] args) {
  
  // declare the type as the interface so that you can mock the Object later
  ParentFace mum = new MyParent();
  showMessage(mum);
  
  // this time try to mock the MyParent 
  mum = new ParentFace() {
   
   @Override
   public void punishChild() {
    System.out.println("pat on the back.");
   }
  };
  
  showMessage(mum);
  
 }

}






The output of this program is:
Kick in the ass!
pat on the back.

Sunday, May 10, 2015

Implement State Pattern Using Enum in Java.

State Pattern is a common design pattern. Let's see how to implement one in Java code using enum.

First we define an Interface: LunchFace with one method declaration: getLunch();
 public interface LunchFace {  
      void getLunch();  
 }  



Then we create an enum to implement the LunchFace interface.
public enum Weekday implements LunchFace{
    MONDAY
    , TUESDAY
    , WEDNESDAY{
        @Override
        public void getLunch() {
            System.out.println("Lunch for " + this.name());
        }
    };

    
    
    @Override
    public void getLunch() {
        System.out.println("lunch for today");
    }

}



Notice here we have the enum implement the LunchFace as a default implementation, we can also have each enum item to have its own implementation by override the getLunch() method.

Now we can test run our code
public class Main {

    public static void main(String[] args) {
        Weekday someday = Weekday.WEDNESDAY;
        someday.getLunch();
        
        someday = Weekday.TUESDAY;
        someday.getLunch();
    
    }

}


And the output should be:
Lunch for WEDNESDAY
lunch for today






Friday, May 8, 2015

Local classes in non-static and static methods

Java code. 
The EnclosingClass has 2 local classes (classes that are defined within a code block). The ShoppingBag class is nested in a non-static method so it has access to all the non-static fields of the enclosing class; the Broom class is defined in a static method so it only has access to all the static fields of the enclosing class. 


Compiler compiles this java file into 3 class files:

EnclosingClass.class
EnclosingClass$1ShoppingBag.class
EnclosingClass$1Broom.class

JVM has no idea that which is the enclosing class and which are the inner classes. So how does it give accesses to the enclosing class' fields to the 2 local classes?

Answer: the compiler creates public static methods inside the EnclosingClass for you automatically:


static int access$0(EnclosingClass);
static java.lang.String access$1(EnclosingClass);
static int access$2();

The Enclosingclass instance is passed in to the local class inside non-static method as a parameter of the constructor and is stored as a field in the EnclosingClass$1ShoppingBag.class

 final EnclosingClass this$0;
    flags: ACC_FINAL, ACC_SYNTHETIC

So the local class inside non-static method accesses the enclosing class' fields by calling access$n methods and passing in the EnclosingClass instance as a parameter.

However, local class inside static method doesn't store the enclosing class instance as a field and notice that the access$2() method doesn't require an enclosing class instance as the parameter, because local class in a static method can only access the static fields of the enclosing class.

Notice that on bytecode level: static methods can access non-static fields.

Now let's look at the bytecode. 

---------------------EnclosingClass$1ShoppingBag.class---------------

class EnclosingClass$1ShoppingBag
  SourceFile: "EnclosingClass.java"
  EnclosingMethod: #20.#40                // EnclosingClass.doShopping
  InnerClasses:
       #43= #1; //ShoppingBag=class EnclosingClass$1ShoppingBag
  minor version: 0
  major version: 51
  flags: ACC_SUPER
Constant pool:
   #1 = Class              #2             //  EnclosingClass$1ShoppingBag
   #2 = Utf8               EnclosingClass$1ShoppingBag
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               numOfBags
   #6 = Utf8               I
   #7 = Utf8               msg
   #8 = Utf8               Ljava/lang/String;
   #9 = Utf8               this$0
  #10 = Utf8               LEnclosingClass;
  #11 = Utf8               <init>
  #12 = Utf8               (LEnclosingClass;)V
  #13 = Utf8               Code
  #14 = Fieldref           #1.#15         //  EnclosingClass$1ShoppingBag.this$0:LEnclosingClass;
  #15 = NameAndType        #9:#10         //  this$0:LEnclosingClass;
  #16 = Methodref          #3.#17         //  java/lang/Object."<init>":()V
  #17 = NameAndType        #11:#18        //  "<init>":()V
  #18 = Utf8               ()V
  #19 = Methodref          #20.#22        //  EnclosingClass.access$0:(LEnclosingClass;)I
  #20 = Class              #21            //  EnclosingClass
  #21 = Utf8               EnclosingClass
  #22 = NameAndType        #23:#24        //  access$0:(LEnclosingClass;)I
  #23 = Utf8               access$0
  #24 = Utf8               (LEnclosingClass;)I
  #25 = Fieldref           #1.#26         //  EnclosingClass$1ShoppingBag.numOfBags:I
  #26 = NameAndType        #5:#6          //  numOfBags:I
  #27 = Methodref          #20.#28        //  EnclosingClass.access$1:(LEnclosingClass;)Ljava/lang/String;
  #28 = NameAndType        #29:#30        //  access$1:(LEnclosingClass;)Ljava/lang/String;
  #29 = Utf8               access$1
  #30 = Utf8               (LEnclosingClass;)Ljava/lang/String;
  #31 = Fieldref           #1.#32         //  EnclosingClass$1ShoppingBag.msg:Ljava/lang/String;
  #32 = NameAndType        #7:#8          //  msg:Ljava/lang/String;
  #33 = Utf8               LineNumberTable
  #34 = Utf8               LocalVariableTable
  #35 = Utf8               this
  #36 = Utf8               LEnclosingClass$1ShoppingBag;
  #37 = Utf8               SourceFile
  #38 = Utf8               EnclosingClass.java
  #39 = Utf8               EnclosingMethod
  #40 = NameAndType        #41:#18        //  doShopping:()V
  #41 = Utf8               doShopping
  #42 = Utf8               InnerClasses
  #43 = Utf8               ShoppingBag
{
  int numOfBags;
    flags: 

  java.lang.String msg;
    flags: 

  final EnclosingClass this$0;
    flags: ACC_FINAL, ACC_SYNTHETIC

  EnclosingClass$1ShoppingBag(EnclosingClass);
    flags: 
    Code:
      stack=3, locals=2, args_size=2
         0: aload_0       
         1: aload_1       
         2: putfield      #14                 // Field this$0:LEnclosingClass;
         5: aload_0       
         6: invokespecial #16                 // Method java/lang/Object."<init>":()V
         9: aload_0       
        10: iconst_3      
        11: aload_1       
        12: invokestatic  #19                 // Method EnclosingClass.access$0:(LEnclosingClass;)I
        15: iadd          
        16: putfield      #25                 // Field numOfBags:I
        19: aload_0       
        20: aload_1       
        21: invokestatic  #27                 // Method EnclosingClass.access$1:(LEnclosingClass;)Ljava/lang/String;
        24: putfield      #31                 // Field msg:Ljava/lang/String;
        27: return        
      LineNumberTable:
        line 11: 0
        line 12: 9
        line 13: 19
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      28     0  this   LEnclosingClass$1ShoppingBag;
}

----------------------EnclosingClass$1Broom------------------------

class EnclosingClass$1Broom
  SourceFile: "EnclosingClass.java"
  EnclosingMethod: #20.#42                // EnclosingClass.cleanHouse
  InnerClasses:
       #45= #1; //Broom=class EnclosingClass$1Broom
  minor version: 0
  major version: 51
  flags: ACC_SUPER
Constant pool:
   #1 = Class              #2             //  EnclosingClass$1Broom
   #2 = Utf8               EnclosingClass$1Broom
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               msg
   #6 = Utf8               Ljava/lang/String;
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Methodref          #3.#11         //  java/lang/Object."<init>":()V
  #11 = NameAndType        #7:#8          //  "<init>":()V
  #12 = Class              #13            //  java/lang/StringBuilder
  #13 = Utf8               java/lang/StringBuilder
  #14 = String             #15            //  Take the broom and start cleaning.
  #15 = Utf8               Take the broom and start cleaning.
  #16 = Methodref          #12.#17        //  java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  #17 = NameAndType        #7:#18         //  "<init>":(Ljava/lang/String;)V
  #18 = Utf8               (Ljava/lang/String;)V
  #19 = Methodref          #20.#22        //  EnclosingClass.access$2:()I
  #20 = Class              #21            //  EnclosingClass
  #21 = Utf8               EnclosingClass
  #22 = NameAndType        #23:#24        //  access$2:()I
  #23 = Utf8               access$2
  #24 = Utf8               ()I
  #25 = Methodref          #12.#26        //  java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  #26 = NameAndType        #27:#28        //  append:(I)Ljava/lang/StringBuilder;
  #27 = Utf8               append
  #28 = Utf8               (I)Ljava/lang/StringBuilder;
  #29 = Methodref          #12.#30        //  java/lang/StringBuilder.toString:()Ljava/lang/String;
  #30 = NameAndType        #31:#32        //  toString:()Ljava/lang/String;
  #31 = Utf8               toString
  #32 = Utf8               ()Ljava/lang/String;
  #33 = Fieldref           #1.#34         //  EnclosingClass$1Broom.msg:Ljava/lang/String;
  #34 = NameAndType        #5:#6          //  msg:Ljava/lang/String;
  #35 = Utf8               LineNumberTable
  #36 = Utf8               LocalVariableTable
  #37 = Utf8               this
  #38 = Utf8               LEnclosingClass$1Broom;
  #39 = Utf8               SourceFile
  #40 = Utf8               EnclosingClass.java
  #41 = Utf8               EnclosingMethod
  #42 = NameAndType        #43:#8         //  cleanHouse:()V
  #43 = Utf8               cleanHouse
  #44 = Utf8               InnerClasses
  #45 = Utf8               Broom
{
  java.lang.String msg;
    flags: 

  EnclosingClass$1Broom();
    flags: 
    Code:
      stack=4, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #10                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: new           #12                 // class java/lang/StringBuilder
         8: dup           
         9: ldc           #14                 // String Take the broom and start cleaning.
        11: invokespecial #16                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
        14: invokestatic  #19                 // Method EnclosingClass.access$2:()I
        17: invokevirtual #25                 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        20: invokevirtual #29                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        23: putfield      #33                 // Field msg:Ljava/lang/String;
        26: return        
      LineNumberTable:
        line 22: 0
        line 23: 4
        line 22: 26
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      27     0  this   LEnclosingClass$1Broom;
}


----------------------EnclosingClass.class--------------------------------
public class EnclosingClass
  SourceFile: "EnclosingClass.java"
  InnerClasses:
       #45= #43; //Broom=class EnclosingClass$1Broom
       #48= #46; //ShoppingBag=class EnclosingClass$1ShoppingBag
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Class              #2             //  EnclosingClass
   #2 = Utf8               EnclosingClass
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               numOfTree
   #6 = Utf8               I
   #7 = Utf8               count
   #8 = Utf8               good
   #9 = Utf8               Ljava/lang/String;
  #10 = Utf8               <clinit>
  #11 = Utf8               ()V
  #12 = Utf8               Code
  #13 = Fieldref           #1.#14         //  EnclosingClass.count:I
  #14 = NameAndType        #7:#6          //  count:I
  #15 = Utf8               LineNumberTable
  #16 = Utf8               LocalVariableTable
  #17 = Utf8               <init>
  #18 = Methodref          #3.#19         //  java/lang/Object."<init>":()V
  #19 = NameAndType        #17:#11        //  "<init>":()V
  #20 = Fieldref           #1.#21         //  EnclosingClass.numOfTree:I
  #21 = NameAndType        #5:#6          //  numOfTree:I
  #22 = String             #23            //  Das ist gut
  #23 = Utf8               Das ist gut
  #24 = Fieldref           #1.#25         //  EnclosingClass.good:Ljava/lang/String;
  #25 = NameAndType        #8:#9          //  good:Ljava/lang/String;
  #26 = Utf8               this
  #27 = Utf8               LEnclosingClass;
  #28 = Utf8               doShopping
  #29 = Utf8               num
  #30 = Utf8               cleanHouse
  #31 = String             #32            //  Take the broom and start cleaning.
  #32 = Utf8               Take the broom and start cleaning.
  #33 = Utf8               message
  #34 = Utf8               access$0
  #35 = Utf8               (LEnclosingClass;)I
  #36 = Utf8               access$1
  #37 = Utf8               (LEnclosingClass;)Ljava/lang/String;
  #38 = Utf8               access$2
  #39 = Utf8               ()I
  #40 = Utf8               SourceFile
  #41 = Utf8               EnclosingClass.java
  #42 = Utf8               InnerClasses
  #43 = Class              #44            //  EnclosingClass$1Broom
  #44 = Utf8               EnclosingClass$1Broom
  #45 = Utf8               Broom
  #46 = Class              #47            //  EnclosingClass$1ShoppingBag
  #47 = Utf8               EnclosingClass$1ShoppingBag
  #48 = Utf8               ShoppingBag
{
  private int numOfTree;
    flags: ACC_PRIVATE

  private static int count;
    flags: ACC_PRIVATE, ACC_STATIC

  private java.lang.String good;
    flags: ACC_PRIVATE

  static {};
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: bipush        20
         2: putstatic     #13                 // Field count:I
         5: return        
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

  public EnclosingClass();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #18                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: bipush        10
         7: putfield      #20                 // Field numOfTree:I
        10: aload_0       
        11: ldc           #22                 // String Das ist gut
        13: putfield      #24                 // Field good:Ljava/lang/String;
        16: return        
      LineNumberTable:
        line 2: 0
        line 4: 4
        line 6: 10
        line 2: 16
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      17     0  this   LEnclosingClass;

  public void doShopping();
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=1
         0: iconst_3      
         1: istore_1      
         2: return        
      LineNumberTable:
        line 9: 0
        line 15: 2
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       3     0  this   LEnclosingClass;
               2       1     1   num   I

  public static void cleanHouse();
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=1, locals=1, args_size=0
         0: ldc           #31                 // String Take the broom and start cleaning.
         2: astore_0      
         3: return        
      LineNumberTable:
        line 20: 0
        line 25: 3
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               3       1     0 message   Ljava/lang/String;

  static int access$0(EnclosingClass);
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: getfield      #20                 // Field numOfTree:I
         4: ireturn       
      LineNumberTable:
        line 4: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

  static java.lang.String access$1(EnclosingClass);
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: getfield      #24                 // Field good:Ljava/lang/String;
         4: areturn       
      LineNumberTable:
        line 6: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

  static int access$2();
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #13                 // Field count:I
         3: ireturn       
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

}

Don't try to start a new Thread and change UI within onCreate() or onResume() methods,

If you try to start a new Thread and change UI within onCreate() or onResume() methods, it's not guaranteed that they will be called.

Do it in a trigger method.


package com.digitalturbine.helloworld;
import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.View;import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

    TextView tvMain;
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);
        tvMain = (TextView) findViewById(R.id.tvMain);

    }


    public void changeText(View view) {
        Runnable runnable = new Runnable() {
            @Override            public void run() {
                tvMain.postDelayed(new Runnable() {
                    @Override                    public void run() {
                        tvMain.setText("Changed from another thread.");                    }
                }, 3000);            }
        };
        new Thread(runnable).start();    }

}

Thursday, May 7, 2015

Android Handler works as a gateway to a MessageQueue in a Looper

A Looper can be associated to multiple Handlers, but a Handler can only be associated to one Looper.


Type token in Java


http://gafter.blogspot.com.au/2006/12/super-type-tokens.html

Java class instantiation procedures.

-------------Jave class------------

public class House {
static int numOfPillars = 4;
private int numOfMembers = 6;
private String nameOfHouse = "The Hom's family";
public House() {
System.out.println(this.getClass().getSimpleName() + " constructor called");
}


}



static fields are initialised when the class is first loaded. 

1. House.<clinit>() method is called, initialise static fields, in this case: numOfPillars;
2. House.<init>() method is called, initialise non-static fields, such as numOfMembers, nameOfHouse;
3. and then House.<init>() calls the constructor public House(){}



Typical class initiation
----------Bytecode Level----------------

 new           #16                 // class Subclass
 dup           
 invokespecial #18                 // Method Subclass."<init>":()V

 astore_2      


new - create new object of type identified by class reference in constant pool index, in this case #16

the duplicate the return value of 'objectref'

invokespecial method consumes one of the two 'objectref' in the stack, calling the <init> method of the class.

and then stores the rest 'objectref' into local variable table

Tuesday, May 5, 2015

final Keyword in Java

final variable can only be initialized once.

It does not need to be initialized at the point of declaration: this is called a "blank final" variable. 

A blank final instance variable of a class must be definitely assigned in every constructor of the class in which it is declared; 

similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.


Final and inner classes[edit]

When an anonymous inner class is defined within the body of a method, all variables declared final in the scope of that method are accessible from within the inner class. 

For scalar values, once it has been assigned, the value of thefinal variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.

In the following example.
The JVM copies the value of the final variable and stores it as a constant in the Constant Pool as 
#16 = Float              3.2f
//--------------------Java---------------------------

public class House {
static final int AGE_OF_THE_HOUSE;
static{
AGE_OF_THE_HOUSE = 50;
}
final int colorOfTheWall;
public House() {
colorOfTheWall = 0x2032;
}
static String paint(String message){
final float width = 3.2f;
class SmallRoom{
float length = 3.5f;
float roomSize = length * width;
}
return "Paint \"" + message + "\" on the wall.";
}
}



-------------------Bytecode-----------------

class House$1SmallRoom
  SourceFile: "House.java"
  EnclosingMethod: #26.#28                // House.paint
  InnerClasses:
       #32= #1; //SmallRoom=class House$1SmallRoom
  minor version: 0
  major version: 50
  flags: ACC_SUPER
Constant pool:
   #1 = Class              #2             //  House$1SmallRoom
   #2 = Utf8               House$1SmallRoom
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               length
   #6 = Utf8               F
   #7 = Utf8               roomSize
   #8 = Utf8               <init>
   #9 = Utf8               ()V
  #10 = Utf8               Code
  #11 = Methodref          #3.#12         //  java/lang/Object."<init>":()V
  #12 = NameAndType        #8:#9          //  "<init>":()V
  #13 = Float              3.5f
  #14 = Fieldref           #1.#15         //  House$1SmallRoom.length:F
  #15 = NameAndType        #5:#6          //  length:F
  #16 = Float              3.2f
  #17 = Fieldref           #1.#18         //  House$1SmallRoom.roomSize:F
  #18 = NameAndType        #7:#6          //  roomSize:F
  #19 = Utf8               LineNumberTable
  #20 = Utf8               LocalVariableTable
  #21 = Utf8               this
  #22 = Utf8               LHouse$1SmallRoom;
  #23 = Utf8               SourceFile
  #24 = Utf8               House.java
  #25 = Utf8               EnclosingMethod
  #26 = Class              #27            //  House
  #27 = Utf8               House
  #28 = NameAndType        #29:#30        //  paint:(Ljava/lang/String;)Ljava/lang/String;
  #29 = Utf8               paint
  #30 = Utf8               (Ljava/lang/String;)Ljava/lang/String;
  #31 = Utf8               InnerClasses
  #32 = Utf8               SmallRoom
{
  float length;
    flags: 

  float roomSize;
    flags: 

  House$1SmallRoom();
    flags: 
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #11                 // Method java/lang/Object."<init>":()V
         4: aload_0       
         5: ldc           #13                 // float 3.5f
         7: putfield      #14                 // Field length:F
        10: aload_0       
        11: aload_0       
        12: getfield      #14                 // Field length:F
        15: ldc           #16                 // float 3.2f
        17: fmul          
        18: putfield      #17                 // Field roomSize:F
        21: return        
      LineNumberTable:
        line 19: 0
        line 20: 4
        line 21: 10
        line 19: 21
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      22     0  this   LHouse$1SmallRoom;
}

Android Launch Mode Illustration


Saturday, May 2, 2015

Defining an Inner Class inside an Interface

Any class that is defined within an Interface is set to be 'public static' by JVM, so the modifier 'static' is not necessary. A static member class is just like another class outside the OuterClass.

Defining a class inside an Interface is purely for the code readability purpose, there is no specially techniques here. For example, if a class is only used by one Interface, it helps the code readability by defining the class inside this Interface.

------------Java-------------------

public interface FunBoy {
int NUM = 3;
class Boy{}

}


-------------Bytecode---------------

public interface FunBoy
  SourceFile: "FunBoy.java"
  InnerClasses:
       public static #14= #12 of #1; //Boy=class FunBoy$Boy of class FunBoy
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
Constant pool:
   #1 = Class              #2             //  FunBoy
   #2 = Utf8               FunBoy
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               NUM
   #6 = Utf8               I
   #7 = Utf8               ConstantValue
   #8 = Integer            3
   #9 = Utf8               SourceFile
  #10 = Utf8               FunBoy.java
  #11 = Utf8               InnerClasses
  #12 = Class              #13            //  FunBoy$Boy
  #13 = Utf8               FunBoy$Boy
  #14 = Utf8               Boy
{
  public static final int NUM;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: int 3

}