Monday, August 25, 2014

Custom android.app.Application and ClassNotFoundException

I've encountered this error so many times... and every single time it was something so stupid I had to waste (in total I would estimate) hours to solve, and sometimes stupidity repeats itself.

So I'll name here a few cases I remember:
  • When you encounter this in your published application, if you haven't done something extremely stupid, like not exporting the application class, then this is mostly an OS update thing... that it tries to launch the application between the removal of the older version and the installation of the newer one.
  • While you see this in your logcat when launching the application from your IDE, it can be one of the following:
    • You do not export the workspace dependencies of your Android application.
    • One or more of your Android libraries paths are incorrect.

Also sometimes you might have an error on your project node in the "package explorer", but all the content of the project seems fine, well this is because one of your Android libraries has one of the above dependency issue.

Hope I saved you a minute... :)

+1 if this helped you!

Monday, June 30, 2014

Upgrading to ADT 23 - Multiple issues

Google I/O 2014 had passed, and with it a breeze of new technologies came along, and of course we developers want to try out what coming.... so we take our IDE that took us hours to config, we take our ADT and Android-SDK that took us hours to download, and upgrade it all to work with the latest version......
...
...
And then it begins....

  • Eclipse will not install the new ADT plugin due to some conflicting dependencies.
  • Files are missing because their names or paths have changed.
  • Features are not working.
  • annotations.jar is missing.
  • zipalign is not there.
  • proguard is gone.
  • ...
  • ..
  • .
  • And only god knows what else I've missed (Or a Google Search)

Thing is about Google they know their shit, and they will not(in most cases) just release something half working, but it would be nice of them to let us(fellow developers) know that we need to reconstruct our work environment from scratch... I mean they should literally state somewhere "TO USE THE NEW ADT YOU MUST... blah blah" so we wont waste days on hoping for a fix that will not come.

So the solution is:

Download the new bundle Eclipse or Android Studio, follow the steps and setup your work environment e.g. your Android SDK and your IDE... then magically everything works.

OK, I've also worked out Proguard:
Go here and copy the content, create a file at: ${SDK}/tools/proguard/proguard-android.txt
(I'm not sure if that is the original content if not post a link to it)

Now go and download Proguard... this is an old bug they didn't bother to fix yet, I had to do this also last time I've installed the SDK, both at home and at work.

Extract the zip onto ${SDK}/tools/proguard/

And you are done, I think this will work on all environments, if not leave me a comment.

If this solves your issue  +1 it so others may find this as well, if not write a comment and lets see how to fix this.

Wednesday, April 30, 2014

Check if all your texts are in the Strings XML

So most people are going to say... whaaat? lint does this for me already...

Well, I hate lint(most of the time!) its a cool tool with tons of potential and zero usage for me!

It actually stand in my way of building testing and releasing my application most of the time, and the warnings are sometimes annoyingly annoying :)

I know you can configure this bugger till you drop, but if I don't use/need it what is the point of wasting a lot of time configuring something that on the next Eclipse Android bundle release would go to waste?

In any case what I do is run this "Search in file", for all XMLs in the project:

android:text="(?!@).*?"

Just don't forget to check the regexp check box to the right under the text field...

This simple regexp checks which of my strings are texts, and which uses the strings file...

Enjoy!

Wednesday, April 16, 2014

Android animation crops the view

I had this simple Animation XML:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="300"
        android:fromXDelta="100%"
        android:toXDelta="-10%" />
    
    <translate
        android:duration="100"
        android:fromXDelta="-10%"
        android:startOffset="300"
        android:toXDelta="0%" />
</set>

Which simply enough should have slide a view from the right, and cross the left border of the screen and then return back to its place.

Simple enough...? Nothing is simple!

As it seemed, the OS cropped the darn view, rendered it with a missing 10% of the view right edge.
I've searched and tried different approaches for hours, (... guys hours for a stupid animation!!!)

After a long while I finally found a blog post from 2011 that made some sense.

Since Chet says, and I agree that these flags, once you are aware of their existence, make clear sense of what they do, and since he explain in detail the 'why', I'm not going to, because he did it magnificently, I'll just sum it up:


fillEnable is by default 'false'
fillAfter is by default 'false', and IS NOT effected by the fillEnabled flag.
fillBefore is by default 'true', and IS effected by the filleEnabled flag.

So to conclude this, here is the solution that worked for me(Note the bold lines):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="300"
        android:fillBefore="false"
        android:fillEnabled="true"
        android:fromXDelta="100%"
        android:toXDelta="-10%" />
    
    <translate
        android:duration="100"
        android:fillBefore="false"
        android:fillEnabled="true"
        android:fromXDelta="-10%"
        android:startOffset="300"
        android:toXDelta="0%" />
</set>

Monday, March 17, 2014

Determine running OS programmatically in Java

I know that most people don't use this, but for the moment you do need it, here is a nice way that you scan detect the running OS in Java:

public enum OSType {
    Windows("win"),
    MacOS("mac", "darwin"),
    Linux("nux"),
    Other("generic");

    private static OSType detectedOS;

    private final String[] keys;

    private OSType(String... keys) {
        this.keys = keys;
    }

    private boolean match(String osKey) {
        for (int i = 0; i < keys.length; i++) {
            if (osKey.indexOf(keys[i]) != -1)
                return true;
        }
        return false;
    }

    public static OSType getOS_Type() {
        if (detectedOS == null)
            detectedOS = getOperatingSystemType(System.getProperty("os.name", Other.keys[0]).toLowerCase());
        return detectedOS;
    }

    private static OSType getOperatingSystemType(String osKey) {
        for (OSType osType : values()) {
            if (osType.match(osKey))
                return osType;
        }
        return Other;
    }
}

Use it wisely, and leave your comments below :)


Thursday, March 13, 2014

Android - Type Safe SharedPreferences

OK, so how many time did you get so pissed because of the way you had to use the SharedPreferences and store stuff on Android?

I know this drove me mad more than once, and the fact I have to copy paste some implementation from one app to another was even more frustrating...

So.......  I've thought a while back to make a generic storage utility object, specifically for Android, (I already have something like that for Pure Java) and after a long while I have. I know this is a bit overkill, but hell, I would gladly pay with few extra lines of code to save hundreds, for a readable, comfortable and quick coding.

If you find the code useful, leave me a comment... I would like to know I'm not doing this for no good reason!

For me the code is pretty obvious, but then again I've been at it for years... let me know what is not clear so I can elaborate more about these subjects.



-- UPDATE --

I've released Cyborg not too long ago, and this sort of generic shared preferences is build in and optimized further in terms of how much code you need to write, You can find it here.