Friday, May 8, 2015

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

}