Saturday, December 5, 2015

Use Gradle to remove 2-digits prefix in filenames recursively


What we have:




We want to remove all the number prefixes in the songs' names. Something like this




import groovy.io.FileType

FileCollection collection
File srcDir = new File('Taylor Swift')

task rename {


    println 'pwd'.execute().text

    def list = []


    srcDir.eachFileRecurse(FileType.FILES) { file ->
        list << file
    }
    list.each {
        changeName(it)
    }
}


def changeName(File file) {

    String regex = "^[0-9][0-9].*"    String originalName = file.getName()



    boolean b = originalName.matches(regex);

    if (b) {
        String newname = originalName.replaceFirst("[0-9][0-9]\\s", "")
        File newNameFile = new File(file.getParent(), newname)
        file.renameTo(newNameFile)

        println newNameFile

    }


}

Script to change all name prefix in a directory


The unix script to remove all file name prefix of 2 digits. example :
03 What is this about.txt



for name in [0-9][0-9]*
do 
    newname="$(echo "$name" | cut -c4-)"
    mv "$name" "$newname"
    echo ${newname}
    
done



This uses bash command substitution to remove the first 3 characters from the input filename via cut, and stores that in $newname. Then it renames the old name to the new name. This is performed on every file.
cut -c4- specifies that only characters after index 4 should be returned from the input. 4- is a range starting at index 7 with no end; that is, until the end of the line.

Reference:

http://unix.stackexchange.com/questions/47367/bulk-rename-change-prefix

Tuesday, November 10, 2015

Sorting when querying



When doing a query in Android the default sorting is to list Capital letters from A-Z first then lower-case letters a-z.

To sort the list alphabetically regardless of the case of the first letter, you need to do the following.


Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
   ContactsContract.Contacts.HAS_PHONE_NUMBER + " = 1", 
   null, 
   "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ") ASC");
 
 
 
Reference
http://stackoverflow.com/a/24489525 

Thursday, October 29, 2015

Fragment transaction can't addToBackstack in Marshmallow

Add this piece of code to the underlying Activity


@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}


Reference:

http://stackoverflow.com/a/28322881

Sunday, October 11, 2015

Using Relative project dependencies in Gradle for Android


First we create an Android project from Android Studio call MyLibrary.
Then remove the applicationId attribute from the build.gradle file and change the plugin from
apply plugin: 'com.android.application'
To
apply plugin: 'com.android.library'

That's all the changes we need to make with the library project.


Go back to our main project: MyApplication.

change the settings.gradle file to include our library project in the build.



Then we can configure our build.gradle file in MyApplication to add the dependency of MyLibrary project. In the dependencies section, add a line

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile project(':mylib')

}

Job done.

References:

http://stackoverflow.com/a/16999835

Wednesday, August 26, 2015

Pointers and Arrays in C - The story of George St


Arrays and Pointers in C-programming are 2 different types used in a similar manner.

To make an analogy, let’s assume that  there is a street called George street. Buildings are built along the street.


The original plan is that every house takes up the same space (1 unit) and each is assigned a street number. The next house has a street number incremented by 1 from the previous one.


So the street number for houses along the street will be 1, 2, 3, 4 … 249, 250. When people want to build a house or go to a friend’s house to pick up something, they ask for the street number and go to the address accordingly.


This works pretty well for a while.


However, a few years later, this suburb is re-zoned for both residential and business uses.


Since then, warehouses have been built in this area. Unlike normal houses, the warehouse takes up twice as much space as a normal house, which is 2 unit of space.


Buildings are no longer the same size, you can’t assume that each street number represents a house anymore.


As a result, people can’t just ask for an address and use that unit of space without telling the planner what type of the building they are planning to build or visiting.


For example, a warehouse is built in the space which was originally planned for house number 204 and 205.


When people apply to build a warehouse starts from number 204,  the land planner writes down that warehouse is assigned street number 204 and it has the size of 2 unit of space.


So we know that the space for street number 204 and 205 are taken since the warehouse has a size of 2 unit of space.


Next time, they have to start from street number 206 to build something else.

A pointer is like a street number from which you can find the address and the type of building or space you want to use. A pointer must have a type or otherwise you don’t know how much space you can use or how big is the building.


When people want to use some space or to visit a building, they go to the land planner and tell him the street number and the type of building they want to visit or plan to build. The land planner gives them a key with a tag, which has the type of building and the starting street number written on it.


Worth mentioning is that: this key can open any door on George Street.


Once the key and street number is given to you, you can feel free to go to the next door and the next door or the previous door … literally you can go wherever you like and do some doggy things in other people’s houses. But the result may not be what you want.

In some situations, you might want to use 3 warehouses in a row.


You can ask the planner to give you an array of 3 warehouses.


He will give you a key with a tag. On the tag it says: starting address 204; type: warehouse: number of elements: 3.


So you know that you can find the first warehouse by going to the address 204, since each warehouse takes up 2 unit of space, the next one will be at address 206 and the next one will be at 208.


Although there is nothing to stop you from going over the boundary of the space assigned to you, you might not want to do so as there might be serious consequences.


Unlike pointer, the address, type, and number of elements of an array cannot be changed as it is the key for you to find all 3 warehouses.  



Tuesday, August 25, 2015

onActivityResult called whenever the starting Activity instance is resumed

If Activity A starts another Activity B by calling the method startActivityForResult(...).

Whenever the same Activity A instance is resumed, the onActivityResult of A is called.

If Activity B starts a new instance of Activity A, then the onActivityResult(...) method is not call.

For example, if Activity B calls startActivity and start a new instance of Activity A on top of the task stack.
Intent startMainActivity = new Intent(this, MainActivity.class);
startActivity(startMainActivity);

The onActivityResult(...) is not called.

But if Activity B starts the same instance of Activity A by using the FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_SINGLE_TOP flags in the intent.

setResult(Activity.RESULT_OK);
Intent startMainActivity = new Intent(this, MainActivity.class);
startMainActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startMainActivity.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(startMainActivity);


Then the onActivityResult(...) is called.

However, the resultCode you passed in through method setResult(...) in Activity B will not be passed through Activity A if A is started by an Intent.

Although the onActivityResult(...) is called, but the resultCode is still 0 (RESULT_CANCELED)

Only if we finish Activity B and expose Activity A on to the top of task stack will pass the resultCode -1 (RESULT_OK) to onActivityResult(...) in Activity A.

setResult(Activity.RESULT_OK);
finish();


Monday, August 10, 2015

How to import an existing Android Studio Project as a Library Module (Step-by-step guide)

In the situation where we have 2 Android Studio projects and we want to use one as a library project which is to be imported to another project as a module. We can easily do that with Android Studio.



Let's assume that we have 2 projects: MyApplication and MyLibrary and we want to import MyLibrary project into MyApplication as a module.


The first thing we need to do is to find the build.gradle file in the module that we want to import from MyLibrary project, which is usually in the app directory unless you changed the name of the module

MyLibrary
      |__app 
             |___build.gradle


 Notice that the build.gradle file plugin is the 'com.android.application' plugin. To use this project as a library project, we need to apply the 'com.android.library' plugin. The file will be like this:



Try to sync the project, an error will occur: Library projects cannot set applicationId.


We can fix that by removing the applicationId line in the gradle file, inside defaultConfig brackets.



That's all for the MyLibrary project. 
Next we move on to the MyApplication project to import MyLibrary as a module.
Go to MyApplication project, click File -> New -> Import Module.


An dialog appears


Navigate to the directory of the Module you want to import from the MyLibrary project. Usually it's the app module unless you've given it another name.


An error will occur if there is a Module in MyApplication project with the same name. To import an updated module from a library project, we can give it a version number in the Module name setting here. 




Change the name of the module to my-library, imported successfully.


Almost there, the last step is to fix the dependencies in MyApplication project. Many people forget to do this.

Start the Project Structure dialog, select the app module(can have another name), and click the dependencies tab on the right side.


Find the plus button and click it, select module dependency on the pop-out menu.




and then select the library module we just imported from MyLibrary project.





Click OK, and it's all done.

What the IDE does for you is to add the dependency in MyApplication/app/build/gradle file.

MyApplication
      |__app 
             |___build.gradle

The dependencies section looks something like this:



dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.0'    
    compile project(':my-library')
}


It might work just fine, but there is potentially a problem, the MyLibrary project has its own dependencies. For example, both MyApplication and MyLibrary can be using support libraries, which might have version conflicts.

We can avoid this by configuration transitive dependencies in gradle.
We can change the line


compile project(':my-library')


to

compile(project(':my-library')){
    transitive=false;
}



This issue will be avoid. Done!




That's all. Happy coding!

Friday, July 17, 2015

How to use an external project as a library project in Android Studio

We have 2 Android projects:
MyApplication is the project that produces apk and to be run on mobile devices;
Dependency is a library project that contains useful classes such as Fragments, Services, Util classes to be used by MyApplication.

The structure of these 2 projects are like this:
MyApplication
  |--build.gradle
  |--settings.gradle
  |--app
  |    |--build.gradle
Dependency
  |--build.gradle
  |--settings.gradle
  |--app
  |    |--build.gradle

First of all, we need to make sure that the gradle plugin of Dependency/app/build.gradle is library instead of application. The first line of the build.gradle file should be this:


apply plugin: 'com.android.library'

Then we go back to the MyApplication project, find the settings.gradle file under the project directory(MyApplication/settings.gradle), edit it to include our Dependency project by adding the lines like this:


include ':library-project-name'
project(':library-project-name').projectDir = new File(settingsDir, '../Dependency/app/')

the second parameter of File(.., ..) is a directory path pointing to the build.gradle file of the app module of the library project.


The last step is to configure the build.gradle file of the app module of the MyApplication project in order to add the library project to its dependencies.

We go to MyApplication/app/build.gradle file and add a line to the dependencies block.


dependencies{
   ........
   compile project(':library-project-name')
}

All done, feel free to use any classes in the Dependency library project in your MyApplication project from this point on.

Wednesday, July 8, 2015

Useful commands for Android Developers on Mac

Check jdk path

/usr/libexec/java_home -v 1.7

Add JDK path to environment variables

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home

Add gradle to path

GRADLE_HOME=/Users/ericliu/Developer/Android/gradle-2.5;
export GRADLE_HOME
export PATH=$PATH:$GRADLE_HOME/bin

Add adb to path

export PATH=$PATH:/Users/ericliu/Library/Android/sdk/platform-tools



Open a file with an Application

open Application.app

Or:


open -a Application filename


Close an Application from Terminal

osascript -e 'quit app "APPLICATIONNAME"'

For example, to quit Calendar from the command line, replace APPLICATIONNAME with “Calendar”
osascript -e 'quit app "Calendar"'



Enable Git auto-completion and add the current branch, and the status of the working directory info to the  prompt
First, download some script files from github and rename them to start with "." so they will become hidden files.

curl -OL https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash

mv git-completion.bash .git-completion.bash

curl -OL https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh

mv git-prompt.sh .git-prompt.sh 



Then edit the .bash_profile file or .profile or .bashrc

# Git config: add the current branch, and the status of the working directory info to the # prompt
. ~/.git-prompt.sh
export GIT_PS1_SHOWDIRTYSTATE=1
export PS1='\w$(__git_ps1 " (%s)")\$ '


# Git config: load the .git-completion.bash file if it exists
if [ -f ~/.git-completion.bash ]; then
    source ~/.git-completion.bash
fi



Now the auto-completion for git is enabled and the prompt line will now display the current branch name. If you go to a git repository directory, the prompt line will now look like this:

~/Developer/Work/MyApplication (master)$ 


View Android Task Stack from command line

adb shell dumpsys activity

To be more concise:

adb shell dumpsys activity activities | sed -En -e '/Stack #/p' -e '/Running activities/,/Run #0/p'

In addition, if you only want to see the activities' name in the stack you can do this:

adb shell <enter> dumpsys activity | grep -i run


Compile a C program file.

gcc HelloWorld.c

And run the compiled result.

./a.out




References:

http://osxdaily.com/2014/09/05/gracefully-quit-application-command-line/

http://stackoverflow.com/questions/2442713/view-the-tasks-activity-stack

Tuesday, June 23, 2015

Why the Outer Class has access to inner Class instances' private fields

Consider a class like this




public class Subclass extends Superclass {
 int subMember;
 

 private void interestingMethod(){
  System.out.println("Subclass is interesting");
 }
 
 @Override
 protected void notSoInteresting() {
  super.notSoInteresting();
  System.out.println("Subclass is not so interesting.");
 }
 
 
 public void accessInnerClassFields(){
  Innerclass innerClass = new Innerclass();
  innerClass.innerClassId = 3;
 }
 
 public class Innerclass{
  private long innerClassId = 32L;
  
  void changeOuterMember(){
   subMember = 3;
  }
 }
 
 public void accessInnerStaticClassFields(){
  EricLiu eric = new EricLiu();
  long copyEricId = eric.ericId;
 }
 
 
 public static class EricLiu{
  private long ericId = 123L;
  
 } 
}


Let's look at the methods accessInnerStaticClassFields() and accessInnerClassFields(). They both access the private fields of an inner class, either a static one or non-static one. How does that happen?
The Java Virtual Machine has no idea that they are inner classes so it should prevent another class from accessing the EricLiu and InnerClass's private class members.

Let's dive into the bytecode. call javap -v -p -s -sysinfo -constants Subclass.class
to dissect the outer class first.



 public void accessInnerClassFields();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=1
         0: new           #37                 // class Subclass$Innerclass
         3: dup           
         4: aload_0       
         5: invokespecial #39                 // Method Subclass$Innerclass."<init>":(LSubclass;)V
         8: astore_1      
         9: aload_1       
        10: ldc2_w        #42                 // long 3l
        13: invokestatic  #44                 // Method Subclass$Innerclass.access$0:(LSubclass$Innerclass;J)V
        16: return        
      LineNumberTable:
        line 23: 0
        line 24: 9
        line 25: 16
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      17     0  this   LSubclass;
               9       8     1 innerClass   LSubclass$Innerclass;

  public void accessInnerStaticClassFields();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: new           #51                 // class Subclass$EricLiu
         3: dup           
         4: invokespecial #53                 // Method Subclass$EricLiu."<init>":()V
         7: astore_1      
         8: aload_1       
         9: invokestatic  #54                 // Method Subclass$EricLiu.access$0:(LSubclass$EricLiu;)J
        12: lstore_2      
        13: return        
      LineNumberTable:
        line 36: 0
        line 37: 8
        line 38: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      14     0  this   LSubclass;
               8       6     1  eric   LSubclass$EricLiu;
              13       1     2 copyEricId   J




Apparently the accessInnerClassFields() method has called an method named:
Subclass$Innerclass.access$0

to access the inner class instance's private field.
and the accessInnerStaticClassFields() method calls the method named:
Subclass$EricLiu.access$0

to access the inner static class instance's private field. So what are these access$0 methods?


Now let's take a look at the bytecode of the inner classes.
We found that the compiler has automatically created a static method inside of both inner classes for the outer class to access the fields. No matter the inner class is a static class or non-static.

Notice at bytecode level, static methods can access non-static fields

 static void access$0(Subclass$Innerclass, long);
    Signature: (LSubclass$Innerclass;J)V
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=3, locals=3, args_size=2
         0: aload_0       
         1: lload_1       
         2: putfield      #19                 // Field innerClassId:J
         5: return        
      LineNumberTable:
        line 28: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature


static long access$0(Subclass$EricLiu);
    Signature: (LSubclass$EricLiu;)J
    flags: ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: getfield      #14                 // Field ericId:J
         4: lreturn       
      LineNumberTable:
        line 35: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

That is the reason why outer class can access inner class instances' private fields.




Thursday, June 11, 2015

Never call setRetainInstance(true) for a Fragment backed by Loaders

Never call setRetainInstance(true) when there is a List inside the Fragment which is backed by a Loader.

Loaders handle configuration changes itself, it will conflict with the saved Fragment instances.

I have run into the following errors a couple of times. By putting breakpoints inside the Android FragmentManager class, I've figured out that it is caused by Loaders calling onLoadFinished(..) while the reference to the Activity is null.

I don't have time to look into the FragmentManager class to figure out what the exact reason is that the mActivity is null right now so I just point it out. Will look into it in the future.


Process: com.ericliudeveloper.sharedbillhelper, PID: 11784 java.lang.NullPointerException at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:950) at android.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:785) at android.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1086) at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:469) at android.content.Loader.deliverResult(Loader.java:144) at android.content.CursorLoader.deliverResult(CursorLoader.java:110) at android.content.CursorLoader.deliverResult(CursorLoader.java:43) at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:265) at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:92) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5748) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107) at dalvik.system.NativeStart.main(Native Method)

Saturday, June 6, 2015

UnsupportedOperationException when testing Android ContentProvider

I was using ProviderTestCase2 to test my ContentProvider in an Android Application but always getting the UnsupportedOperationException when I tried to do any CRUD operation with my
MockContentResolver, the error message is as follow:


java.lang.UnsupportedOperationException
at android.test.mock.MockContext.openOrCreateDatabase(MockContext.java:222)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)

Eventually I figured out it's all because of this line in my onCreate method of my Provider:

dbHelper = new BillDatabaseHelper(getContext().getApplicationContext());

Because the Context I gave to the Provider is the Application Context so during a test, it's looking for the Application Context instead of the MockContext that is given by the system during testing.

After changing my onCreate method of the Provider to the following, everything works like a charm.

@Overridepublic boolean onCreate() {
   dbHelper = new BillDatabaseHelper(getContext());   return (dbHelper == null) ? false : true;}

Thursday, June 4, 2015

Fixing the Toolbar or Actionbar being overlapped by the Android System Status bar problem.


When I was trying out the new Design Support Library (compile 'com.android.support:design:22.2.0')
and using the Toolbar to replace the Actionbar.

A problem occurs on Android 5.0 devices where the Toolbar goes under the system Status Bar and leaves a empty space on top of the main layout as the following picture shows.


To fix this, we add an attribute to the Layout of this activity:
android:fitsSystemWindows="true"

This attribute is boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.

The fitsSystemWindows attribute makes your Layout View fit to the edges of the action bar and navigation bar (instead of going under them).

Then the problem is fixed and the display is exactly what we want it to be.


Tuesday, June 2, 2015

Android selector important fact

Note: Remember that Android applies the first item in the state list that matches the current state of the object. So, if the first item in the list contains none of the state attributes above, then it is applied every time, which is why your default value should always be last.



The following snippet will never show the checked state because when the system compares the state against the first item, it always matches as there is no specific state of it.



<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="@android:integer/config_shortAnimTime">


    <item>
        <bitmap android:src="@android:drawable/ic_input_add" />
    </item>


    <item android:state_checked="true">
        <bitmap android:src="@android:drawable/star_big_on" />
    </item>


</selector>

Change the order of items and it works.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
    android:enterFadeDuration="@android:integer/config_shortAnimTime"
    >


    <item android:state_checked="true">
        <bitmap android:src="@android:drawable/star_big_on"/>
    </item>

    <item>
        <bitmap android:src="@android:drawable/ic_input_add"/>
    </item>



</selector>

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.