Monthly Archives: April 2015

Android Support Library v22.1 轻度使用感受

前两天Google出了新的Support Library v22.1,这两天轻度使用了一下,贴点使用感受,慢慢更新

  1. Google又改Activity的基类了,原来是ActionbarActivity,现在是AppCompatActivity。很多逻辑也发生变化,之前是用Toolbar作为Actionbar的,现在也不需要了,直接自带Actionbar了,也是Material Design的设计,这个改动如果是从新写App的话挺好,如果是之前的老项目。。估计要改的吐血吧
  2. 各种Material Design的组件更新极其缓慢,这次确实又加了几个,但是设置不了深度,从用户的角度根本看不出来有多大变化。Annimation什么的通通没有,Google看这样子是不打算支持4.x用户了么?
  3. AlertDialog出了新的了,改下import就行了,好评。

发现一个有趣的东西:Docker

最近在写一个新的应用,后端用的是Nginx +  Python + Django + Gunicorn + Celery + libav,Celery又依赖RabbitMQ,为了让Celery和Gunicorn跑起来又用了Supervisor,东西太多配置又太繁琐,写代码调试和部署都是一个挑战,时间长了怕是配置文件和日志的location都要忘光光。我的工作环境是Mac和Windows,服务器则是Ubuntu或者Centos,像libav这种东西基本上算是Linux独有的,Mac虽然是*nix like但是毕竟不是Linux,想了半天最后决定放弃在Mac做Celery worker的调试,改在Ubuntu的服务器上用最原始的Log来分析调试,简直蛋疼到不行。

这两天在网上看到了Docker这个玩意,看起来确实不错:在Linux上有近乎Native的性能,在其它平台上则通过类似虚拟机的机制来构建运行环境,通过remote debug机制和IDE沟通,而部署则有点像拷贝虚拟机镜像:Docker的每一个优势都直击开发部署的痛点,下次部署的时候一定要用一下。

愿让我满怀期望的Docker,不要像Cygwin一样让我失望。

Overload vs Override, Java vs Groovy

Groovy is one of my favorite languages. It is simple yet powerful. More importantly, it can be integrated into Java stack easily, bringing us thousands of libraries that are ready to use.

One interesting thing about Java and Groovy is the difference in treating overload. A lot of scripting languages do not have function overloading. For example, in Python you need to use named parameters if you want to have some kinds of workaround for that. In JavaScript you need to check if a parameter is defined manually in the function, which brings complexity and lacks intuition. Same things happen to Matlab, where you have to check the number of arguments like the old C code:

int main(int argc, char** args);

Java has overloading, and it is reasonable that Groovy also has overloading. However, they treat overloading differently.

Java dispatch overloading during compile time. In other words, it is fixed and cannot be changed during run-time. However, as a dynamic language, Groovy dispatch overloading at run-time, which causes a different result in the following program.

//Java Code
public class TestJava
{
   public void print(Object a)
   {
      System.out.println("Object");
   }


   public void print(String a)
   {
      System.out.println("String");
   }

   public static void main(String[] args)
   {
      TestJava test = new TestJava();
      String s = "Hello World";
      Object o = s;
      test.print(s);
      test.print(o);
   }
}
//Groovy Code
class TestGroovy {
    public void print(Object a)
    {
        System.out.println("Object");
    }


    public void print(String a)
    {
        System.out.println("String");
    }

    public static void main(String[] args)
    {
        TestGroovy test = new TestGroovy();
        String s = "Hello World";
        Object o = s;
        test.print(s);
        test.print(o);
    }
}

These two pieces of code are identical to each other, except for the class name. However, the results are quite different. In Java, the output is String and Object, while in Groovy, the output is String and String.

What if we call the Java code in Groovy, and call the Groovy code in Java?

//Java Code
public class TestJava
{
   public void print(Object a)
   {
      System.out.println("Object");
   }

   public void print(String a)
   {
      System.out.println("String");
   }

   public static void main(String[] args)
   {
      String s = "Hello World";
      Object o = s;
      TestGroovy groovy = new TestGroovy();
      groovy.print(s);
      groovy.print(o);
   }
}
//Groovy Code
class TestGroovy {
    public void print(Object a)
    {
        System.out.println("Object");
    }


    public void print(String a)
    {
        System.out.println("String");
    }

    public static void main(String[] args)
    {
        String s = "Hello World";
        Object o = s;
        TestJava java = new TestJava();
        java.print(s);
        java.print(o);
    }
}

For the Java code, the output is String and Object, and for Groovy, String and String.

This experiment tells us the only deciding factor of which kind of dispatch method is being used is your code type that you are actually writing. If you are writing Java, not matter you are referring a code from Java or Groovy,  overloading functions are dispatched at compile time. If you are writing Groovy, overloading functions are dispatched at run time. This brings us a very essential problem: we need to be really careful with overloaded functions that come from Java library when we are writing Groovy code: it is the devil in the detail.

The good news is that, for function override, both Java and Groovy treat it in run-time and share the same behaviour.