Sunday, January 26, 2014

Just when you thought you knew a lot about development...

Just when you thought you knew a lot about development someone that knows more punch you directly in the face with a few wise words.

A friend recommended me "Clean Code" and "Clean Coder", by Robert Martin.

I feel like a child learning everything again. I love these books, it is the kind of technical thing that you need to read before going to sleep.

Wednesday, November 14, 2012

Android SDK Manager can't find latest updates!

I had a nice surprise today. After updating the ADT plugin in Eclipse it says that I must update the android tools.

Ok, one more time I opened the SDK Manager and searched for the updates. But wait... there is no updates. And Eclipse doesn't work! WTF?

"It must be a bad nightmare, take it easy" I think. Just do the obvious thing, close the SDK Manager and open it again. Stupid solution, it doesn't work.

Ok, something is bad, so I enter to the preferences and what I see is "Cache size" with the option "Delete cache". Oh yea! Now it works. God exists.

Stupid cache, you think you know everything, but I am better than you :D

Tuesday, November 6, 2012

Development tools I can't live without

Every developer has his own set of preferred tools. Me too. In my case all these tools are Java oriented because is the language I use more often. Obviously these are not the best tools you can find on internet, I'm sure you use other tools better and you hate my tools, but they gave me so many satisfactions that I think my work can't be finished without them. Too bad uh?

  • Eclipse: "naaaaaaaaaaa, no way" maybe you think. I understand people complaining this fantastic IDE, but I am in love with this tool. I tried all IntelliJ, Netbeans, etc. and I think I know Eclipse so well that I can face any problem that it can have, I accept it's buggy due to the free plugins we install all the time.
  • Findbugs: great free tool to detect common programming problems.
  • CheckStyle: the best tool to detect coding standard violations. I use it inside Eclipse of course.
  • UCDetector: Unused Code Detector. When your project it's really big you notice a lot of code that it is not being used. You can remove it automatically with proguard, but the best option is to delete it. Less code, less problems. This free Eclipse plugin will do the hard work for you, with many options, and allowing to remove multiple things with quickfix.
  • ASM Bytecode Plugin: amazing plugin to see the java bytecode in real time. Sometimes when you want to improve something it is good to check the bytecode, you will get some nice surprises. You can change the code, but the bytecode could be exactly the same or even worst.
  • Lint: checks for problems in Android projects. It is included in the android SDK and the ADT plugin.
  • Total Commander: wtf? This is not for java. Of course not, it is only THE file commander. Extremely powerful, and with lot of free plugins. It's for windows only but I use it with "wine" in MacOS. If you create a plugin the author will send you a personal license for free! Thanks Ghisler, you made me happy on christmas ;)
  • Sonar: easily receive reports with code coverage and errors.
  • PlantUML: combined with Javadoc is an amazing tool to add UML graphs to your documentation.
  • Google: do I need to put the link? When you don't know something he knows it :D
And the last thing I can say is: use the tools that are more comfortable for you, and use them well and wisely. You will love your daily job.



Wednesday, October 19, 2011

What I want to see in Logcat plugin for Eclipse

The new logcat plugin is cool, now has regex and more options to filter. But it lacks of:

  • highlight searched text
  • syntax coloring for XML and others
  • selection of log format (brief, full, etc.) and ring buffer (main, radio, events)
I developed a small logcat plugin with those both features. Warning, this logcat plugin is ugly (I'm not a UI designer), it's just a small example.

You can download it here:!123

A few screenshots

highlight searched text in yellow

syntax highlight in XML

I will continue using the original logcat plugin, is really great, but still has many things to improve. Congratulations to all the developers, they did a great job.


Wednesday, August 31, 2011

Tuesday, May 31, 2011

Obfuscate android builds using proguard

The new android SDK comes with proguard included in the build system. You can check how to use it at

Not all the proguard options can be used, specially those used for optimizations.

You should keep all classes used in xml files. The best way to do it is to keep classes that extend from android.content.Context due to almost everything related to android UI and services belong to the android context.

After some research I give you the best proguard.cfg for almost any application.

-optimizations !code/simplification/arithmetic
-optimizationpasses 5
-target 1.6
# -repackageclasses mypackage

-keep public class * extends android.content.Context {
  *** (...);

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);

-keepattributes Exceptions, InnerClasses, Signature

# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,allowshrinking class * {
    native ;

-assumenosideeffects public class android.util.Log {
  *** *(...);

# Remove - System method calls. Remove all invocations of System
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.System {
    public static long currentTimeMillis();
    static java.lang.Class getCallerClass();
    public static int identityHashCode(java.lang.Object);
    public static java.lang.SecurityManager getSecurityManager();
    public static java.util.Properties getProperties();
    public static java.lang.String getProperty(java.lang.String);
    public static java.lang.String getenv(java.lang.String);
    public static java.lang.String mapLibraryName(java.lang.String);
    public static java.lang.String getProperty(java.lang.String,java.lang.String);

# Remove - Math method calls. Remove all invocations of Math
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.Math {
    public static double sin(double);
    public static double cos(double);
    public static double tan(double);
    public static double asin(double);
    public static double acos(double);
    public static double atan(double);
    public static double toRadians(double);
    public static double toDegrees(double);
    public static double exp(double);
    public static double log(double);
    public static double log10(double);
    public static double sqrt(double);
    public static double cbrt(double);
    public static double IEEEremainder(double,double);
    public static double ceil(double);
    public static double floor(double);
    public static double rint(double);
    public static double atan2(double,double);
    public static double pow(double,double);
    public static int round(float);
    public static long round(double);
    public static double random();
    public static int abs(int);
    public static long abs(long);
    public static float abs(float);
    public static double abs(double);
    public static int max(int,int);
    public static long max(long,long);
    public static float max(float,float);
    public static double max(double,double);
    public static int min(int,int);
    public static long min(long,long);
    public static float min(float,float);
    public static double min(double,double);
    public static double ulp(double);
    public static float ulp(float);
    public static double signum(double);
    public static float signum(float);
    public static double sinh(double);
    public static double cosh(double);
    public static double tanh(double);
    public static double hypot(double,double);
    public static double expm1(double);
    public static double log1p(double);

# Remove - Number method calls. Remove all invocations of Number
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.* extends java.lang.Number {
    public static java.lang.String toString(byte);
    public static java.lang.Byte valueOf(byte);
    public static byte parseByte(java.lang.String);
    public static byte parseByte(java.lang.String,int);
    public static java.lang.Byte valueOf(java.lang.String,int);
    public static java.lang.Byte valueOf(java.lang.String);
    public static java.lang.Byte decode(java.lang.String);
    public int compareTo(java.lang.Byte);
    public static java.lang.String toString(short);
    public static short parseShort(java.lang.String);
    public static short parseShort(java.lang.String,int);
    public static java.lang.Short valueOf(java.lang.String,int);
    public static java.lang.Short valueOf(java.lang.String);
    public static java.lang.Short valueOf(short);
    public static java.lang.Short decode(java.lang.String);
    public static short reverseBytes(short);
    public int compareTo(java.lang.Short);
    public static java.lang.String toString(int,int);
    public static java.lang.String toHexString(int);
    public static java.lang.String toOctalString(int);
    public static java.lang.String toBinaryString(int);
    public static java.lang.String toString(int);
    public static int parseInt(java.lang.String,int);
    public static int parseInt(java.lang.String);
    public static java.lang.Integer valueOf(java.lang.String,int);
    public static java.lang.Integer valueOf(java.lang.String);
    public static java.lang.Integer valueOf(int);
    public static java.lang.Integer getInteger(java.lang.String);
    public static java.lang.Integer getInteger(java.lang.String,int);
    public static java.lang.Integer getInteger(java.lang.String,java.lang.Integer);
    public static java.lang.Integer decode(java.lang.String);
    public static int highestOneBit(int);
    public static int lowestOneBit(int);
    public static int numberOfLeadingZeros(int);
    public static int numberOfTrailingZeros(int);
    public static int bitCount(int);
    public static int rotateLeft(int,int);
    public static int rotateRight(int,int);
    public static int reverse(int);
    public static int signum(int);
    public static int reverseBytes(int);
    public int compareTo(java.lang.Integer);
    public static java.lang.String toString(long,int);
    public static java.lang.String toHexString(long);
    public static java.lang.String toOctalString(long);
    public static java.lang.String toBinaryString(long);
    public static java.lang.String toString(long);
    public static long parseLong(java.lang.String,int);
    public static long parseLong(java.lang.String);
    public static java.lang.Long valueOf(java.lang.String,int);
    public static java.lang.Long valueOf(java.lang.String);
    public static java.lang.Long valueOf(long);
    public static java.lang.Long decode(java.lang.String);
    public static java.lang.Long getLong(java.lang.String);
    public static java.lang.Long getLong(java.lang.String,long);
    public static java.lang.Long getLong(java.lang.String,java.lang.Long);
    public static long highestOneBit(long);
    public static long lowestOneBit(long);
    public static int numberOfLeadingZeros(long);
    public static int numberOfTrailingZeros(long);
    public static int bitCount(long);
    public static long rotateLeft(long,int);
    public static long rotateRight(long,int);
    public static long reverse(long);
    public static int signum(long);
    public static long reverseBytes(long);
    public int compareTo(java.lang.Long);
    public static java.lang.String toString(float);
    public static java.lang.String toHexString(float);
    public static java.lang.Float valueOf(java.lang.String);
    public static java.lang.Float valueOf(float);
    public static float parseFloat(java.lang.String);
    public static boolean isNaN(float);
    public static boolean isInfinite(float);
    public static int floatToIntBits(float);
    public static int floatToRawIntBits(float);
    public static float intBitsToFloat(int);
    public static int compare(float,float);
    public boolean isNaN();
    public boolean isInfinite();
    public int compareTo(java.lang.Float);
    public static java.lang.String toString(double);
    public static java.lang.String toHexString(double);
    public static java.lang.Double valueOf(java.lang.String);
    public static java.lang.Double valueOf(double);
    public static double parseDouble(java.lang.String);
    public static boolean isNaN(double);
    public static boolean isInfinite(double);
    public static long doubleToLongBits(double);
    public static long doubleToRawLongBits(double);
    public static double longBitsToDouble(long);
    public static int compare(double,double);
    public boolean isNaN();
    public boolean isInfinite();
    public int compareTo(java.lang.Double);
    public (byte);
    public (short);
    public (int);
    public (long);
    public (float);
    public (double);
    public (java.lang.String);
    public byte byteValue();
    public short shortValue();
    public int intValue();
    public long longValue();
    public float floatValue();
    public double doubleValue();
    public int compareTo(java.lang.Object);
    public boolean equals(java.lang.Object);
    public int hashCode();
    public java.lang.String toString();

# Remove - String method calls. Remove all invocations of String
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.String {
    public ();
    public (byte[]);
    public (byte[],int);
    public (byte[],int,int);
    public (byte[],int,int,int);
    public (byte[],int,int,java.lang.String);
    public (byte[],java.lang.String);
    public (char[]);
    public (char[],int,int);
    public (java.lang.String);
    public (java.lang.StringBuffer);
    public static java.lang.String copyValueOf(char[]);
    public static java.lang.String copyValueOf(char[],int,int);
    public static java.lang.String valueOf(boolean);
    public static java.lang.String valueOf(char);
    public static java.lang.String valueOf(char[]);
    public static java.lang.String valueOf(char[],int,int);
    public static java.lang.String valueOf(double);
    public static java.lang.String valueOf(float);
    public static java.lang.String valueOf(int);
    public static java.lang.String valueOf(java.lang.Object);
    public static java.lang.String valueOf(long);
    public boolean contentEquals(java.lang.StringBuffer);
    public boolean endsWith(java.lang.String);
    public boolean equalsIgnoreCase(java.lang.String);
    public boolean equals(java.lang.Object);
    public boolean matches(java.lang.String);
    public boolean regionMatches(boolean,int,java.lang.String,int,int);
    public boolean regionMatches(int,java.lang.String,int,int);
    public boolean startsWith(java.lang.String);
    public boolean startsWith(java.lang.String,int);
    public byte[] getBytes();
    public byte[] getBytes(java.lang.String);
    public char charAt(int);
    public char[] toCharArray();
    public int compareToIgnoreCase(java.lang.String);
    public int compareTo(java.lang.Object);
    public int compareTo(java.lang.String);
    public int hashCode();
    public int indexOf(int);
    public int indexOf(int,int);
    public int indexOf(java.lang.String);
    public int indexOf(java.lang.String,int);
    public int lastIndexOf(int);
    public int lastIndexOf(int,int);
    public int lastIndexOf(java.lang.String);
    public int lastIndexOf(java.lang.String,int);
    public int length();
    public java.lang.CharSequence subSequence(int,int);
    public java.lang.String concat(java.lang.String);
    public java.lang.String replaceAll(java.lang.String,java.lang.String);
    public java.lang.String replace(char,char);
    public java.lang.String replaceFirst(java.lang.String,java.lang.String);
    public java.lang.String[] split(java.lang.String);
    public java.lang.String[] split(java.lang.String,int);
    public java.lang.String substring(int);
    public java.lang.String substring(int,int);
    public java.lang.String toLowerCase();
    public java.lang.String toLowerCase(java.util.Locale);
    public java.lang.String toString();
    public java.lang.String toUpperCase();
    public java.lang.String toUpperCase(java.util.Locale);
    public java.lang.String trim();

# Remove - StringBuffer method calls. Remove all invocations of StringBuffer
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.StringBuffer {
    public ();
    public (int);
    public (java.lang.String);
    public (java.lang.CharSequence);
    public java.lang.String toString();
    public char charAt(int);
    public int capacity();
    public int codePointAt(int);
    public int codePointBefore(int);
    public int indexOf(java.lang.String,int);
    public int lastIndexOf(java.lang.String);
    public int lastIndexOf(java.lang.String,int);
    public int length();
    public java.lang.String substring(int);
    public java.lang.String substring(int,int);

# Remove - StringBuilder method calls. Remove all invocations of StringBuilder
# methods without side effects whose return values are not used.
-assumenosideeffects public class java.lang.StringBuilder {
    public ();
    public (int);
    public (java.lang.String);
    public (java.lang.CharSequence);
    public java.lang.String toString();
    public char charAt(int);
    public int capacity();
    public int codePointAt(int);
    public int codePointBefore(int);
    public int indexOf(java.lang.String,int);
    public int lastIndexOf(java.lang.String);
    public int lastIndexOf(java.lang.String,int);
    public int length();
    public java.lang.String substring(int);
    public java.lang.String substring(int,int);