Launched some new apps lately:
Wolfram Alpha RSS
Mom Finds RSS
Hello Giggles RSS
Brain Pickings RSS
Ceiling Fan Calculator
Space Heater Calculator
Andrew McSherry's blog about tech-related stuff that really needs to be updated more often :)
Friday, January 25, 2013
Monday, January 21, 2013
Tuesday, January 15, 2013
New Google Analytics Console
Huge fan of the new Google Analytics redesign. It's nice to not have to switch over to tab sections to see real-time stats, shortcuts, dashboards and intelligence events. Here's a snapshot of the new left navigation panel.
Sunday, January 13, 2013
Using Proguard with Android
Some reasons you might want to use it
Security
Proguard makes it easier to hide the implementation details and keys of the services you use.
Protect IP
The work involved in creating your project is often the primary reason you don't have competitors. Proguard obfuscates your code so your competitors can't simply decompile copy/paste your work.
Reduce APK Size
Proguard removes unused code, reduces the length of variable names, and inlines code. All this adds up to a smaller app size and less for your users to download.
Optimization
Proguard optimizes variable allocation, arithmetic, unnecessary code, etc.
Logging
Proguard can remove all your logging by removing the actual code that calls it. This is much simpler and more efficient than any other method.
Syntax
- http://proguard.sourceforge.net/#manual/usage.html
- # is used for comments
- Always use fully-qualified class names
Reflection
Reflection is easily the biggest gotcha when it comes to Proguard. It works by analyzing which methods and classes actually get used. Despite some safeguards, it's generally best to assume reflected code will get removed. You need to specify which methods and classes to keep. Generally, you should be as specific as possible because telling Proguard to keep large chunks of code drastically reduces it's efficacy.Setting up your proguard.cfg
Initial Template
#Remove all the injar/outjar/libraryjar junk, the android ant script takes care of this
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
First thing you should notice, is that we tell Proguard to keep all the classes (Activities, Services, etc) we declare in AndroidManifest.xml. These are known as the entry points to the application. These classes should not have their names changed because the Android won't be able to find them when needed.
Fragments
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
Fragments are generally created through reflection. It's a good idea to keep them all.
3rd Party Libraries
-keep class android.** {*;}
-keep class com.millennialmedia.android.** {*;)
-keep class com.google.ads.** {*;}
Removing Logging
-assumenosideeffects class android.util.Log {
public static *** e(...);
public static *** w(...);
public static *** wtf(...);
public static *** d(...);
public static *** v(...);
}
assumenosideeffects tells Proguard that method calls to these don't actually do anything and can be removed if the return value is not used. android.util.Log does have a return value that's not particularly useful so keep this in mind.
Serializables
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
I'm not entirely sure why this isn't just build into the platform. These methods and fields from Serializable are discovered at runtime and won't be used in your code.
Click Methods
-keepclassmembers class * {
public void *ButtonClicked(android.view.View);
}
Methods that are called by android:onclick in your xml layouts are referenced by reflection at runtime. My strategy is to suffix them all with ButtonClicked and save any method that ends with that.
Native Methods
-keepclasseswithmembernames class * {
native <methods>;
}
Native methods should not be obfuscated because they reference JNI methods relating to their name.
Obfuscating debug builds
It may be useful to obfuscate debug builds in a continuous integration environment. If so, you can modify your Android build.xml this way to accomplish it.<target name="-debug-obfuscation-check">
<!-- yes, we want to obfuscate in debug too!!!! -->
<condition property="proguard.enabled" value="true" else="false">
<and>
<isset property="proguard.config" />
</and>
</condition>
<if condition="${proguard.enabled}">
<then>
<!-- Secondary dx input (jar files) is empty since all the
jar files will be in the obfuscated jar -->
<path id="out.dex.jar.input.ref" />
</then>
</if>
</target>
Air Conditioning App
Published a new Android app today to help users find the perfect-sized window air conditioner for their home. Branded for my friends' general contracting and remodeling company, The Chateau Group
Air Conditioner Calculator on Google Play
Air Conditioner Calculator on Google Play
Friday, January 11, 2013
Monday, January 7, 2013
Friday, January 4, 2013
O-H!
Lawrence, I love that you follow my blog. However, it really bothers me that there's a Michigan logo in my sidebar.
Thursday, January 3, 2013
Using Campaign Tracking to Send a Message
I put campaign tracking on nearly every link I sent to the web. It's not just about finding out where your traffic is coming from, but also leaving an impression on other developers that you're sending traffic too.
There's another useful method for this: sending messages to a site that have the potential to be very visible to someone that can make decisions. When you send a message to customer support, it gets mixed in with the general opinion of the user-base and then transferred on to product and marketing. Chances are, your opinion doesn't make it past the support team. However, employees at the company looking at analytics are often employees trying to make practical product decisions based on this data. You hit them directly this way.
Suppose you visit my website, and decide you'd love to tell me how wonderful it is. You could send me a message with:
http://www.andymcsherry.com?utm_source=andy%20admirer&utm_medium=address%20bar&utm_campaign=letting%20people%20know%20they%20rock
There's another useful method for this: sending messages to a site that have the potential to be very visible to someone that can make decisions. When you send a message to customer support, it gets mixed in with the general opinion of the user-base and then transferred on to product and marketing. Chances are, your opinion doesn't make it past the support team. However, employees at the company looking at analytics are often employees trying to make practical product decisions based on this data. You hit them directly this way.
Suppose you visit my website, and decide you'd love to tell me how wonderful it is. You could send me a message with:
http://www.andymcsherry.com?utm_source=andy%20admirer&utm_medium=address%20bar&utm_campaign=letting%20people%20know%20they%20rock
Subscribe to:
Posts (Atom)