Brain Flush

November 16, 2009

Introducing Droid-Fu for Android: BetterActivity, BetterService and BetterAsyncTask

Filed under: Software Development & Programming — Tags: , — Matthias @ 9:54 pm

This is the first in a series of posts about Droid-Fu, a shiny new shared library for Android application developers. In this post I will introduce some of the ideas behind Droid-Fu, and start by showing off some of its core features.

What is Droid-Fu?

  • Droid-Fu is a general purpose Android application library, deployed as a JAR
  • Droid-Fu’s primary purpose is to make your Android developer life easier
  • Droid-Fu is open source! (fork it, hack it, share it, all on GitHub)
  • ain’t that enough?

Droid-Fu contains utility classes as well as some self-contained, ready to use Android components, all of which I consider useful for typical Android applications. Some of the areas for which Droid-Fu offers support classes include:

  • application life-cycle
  • background tasks
  • HTTP messaging
  • (remote) image handling
  • custom adapters

… and more. The library is still young, so expect to see a lot more stuff forthcoming!

Who uses it?

Droid-Fu contains mostly code which I pulled from Qype Radar, our geo-sensitive mobile application which let’s you find, review, and share all those cool places near you. In other words, Droid-Fu is used in a production quality app, and even though it’s a WIP, we find it to be quite solid. Of course you’re invited to make it even better. Did I mention it’s open source?

The Foundations

One of the strongest (in my opinion) benefits of using Droid-Fu are its application life-cycle helpers. If you are developing an application which performs background work, such as fetching data from the web, you will almost definitely want to Droid-Fu-idize your app. Here’s why.

That Dratted AsyncTask

I’ve written about this two times now. I think with this third approach, which made it into this library, I finally found a decent solution. But, let’s review the biggest problem with Android’s AsyncTask, first. What is AsyncTask? It’s Android’s helper class you’re supposed to use for performing expensive (that means, blocking) operations. If you’re writing an app that talks to a web service, you’ve very likely already used it. (You’re not doing all that work on the UI thread, do you? If you do, chances are your activity will only live for a couple seconds, because Android kills non-responsive activities. ANR, anyone?)

So the basic idea is: launch an AsyncTask making your service call, show a nifty progress dialog while the task thread is running, and have the task’s result be posted back to your activity once it completes. Cool, but what if the user decides to rotate the screen while your task is running? Or a phone call comes in, interrupting your app, and Android decides to kill it? Both these actions will effectively terminateyour activity, and recreate it when resuming (yes, a screen rotation kills your activity, very clever, isn’t it?). Unfortunately, any AsyncTask that was still running now holds a stale reference to your activity, because the restarted activity will be an entirely different object in memory (and it will go through onCreate(), as if the activity had started for the first time). I’m not entirely sure whether AsyncTask will actually post back the data to the old activity object (if it was a weak reference, it may already have been garbage collected), but in any case, your “new” activity will never see it, because it’s a different instance.

Now, one could argue: well, just do all the work again, like, re-send the request or whatever job was running. Yes, you could do that. But that’s wasteful and, really, makes you feel stupid, no? Plus, if the user triggers a web service request, then flips the screen, decides that this wasn’t helpful, and flips it back, then your request is being sent 3 times in parallel. Is that what you want? Probably not.

BetterAsyncTask to the Rescue

Thanks to Droid-Fu, there’s a solution to this: BetterAsyncTask! (I’m a lazy person, and I couldn’t come up with a better name). It behaves exactly like AsyncTask (in fact, it is an AsyncTask), but it does some extra work for you: first and foremost, it keeps track of the active instance of the context that launched it, and if that instance should change, it will post the data back to the new instance. In other words, you can dispatch your task, flip the screen back and forth mentally, and BetterAsyncTask will still post the task’s result back to whatever activity instance is alive at the time it finishes. In other words, the task is only ever run once, regardless whether the context in which it was launched died while it was running or not.

There’s a catch though. Since there is no way for BetterAsyncTask to figure out which one is the current instance of its activity, it relies on a helper: DroidFuApplication. This class derives from Application, and if you want to use BetterAsyncTask, your application has to derive from that class, otherwise it won’t work. That’s because DroidFuApplication keeps a hash of WeakReferences mapping contexts (activites and services) to their active instances, and when a BetterAsyncTask finishes, it will ask your application for the active instance.

This is all you have to do to launch a task showing the standard Android indeterminate progress dialog:

public class MyActivity extends BetterDefaultActivity {

 protected void onResume() {
   super.onResume();

   if (isLaunching()) { // this is explained further down this article
     MyBetterAsyncTask task = new MyBetterAsyncTask(this);
     task.execute(someData);
   }
 }

}

It doesn’t end here though. BetterAsyncTask does other cool stuff, such as automatically opening and closing progress dialogs for you while it’s running, or triggering that little progress spinner in the activity title bar when your activity has enabled that feature. It also allows your task to throw exceptions in its worker method, which are then posted to an error handler you define. Some of that stuff, like spawning dialogs, only works if your activities inherit from BetterActivity, which I will get to now.

BetterActivity and BetterService: Pimp my context!

Droid-Fu provides base classes for your activities and services which provide some simple but very useful helper methods. Currently, there are only BetterDefaultActivity, BetterListActivity and BetterService, but I intend to implement the Better* stuff for all stock Android activity base classes (like MapActivity and all the others).

Here is what you get:

Life-cycle helpers

these methods let you conditionally perform work depending on a context’s life-cycle state.

  • isLaunching() is true if and only if the context just went through onCreate() for the first time (but was not restored, i.e. onRestoreInstanceState() was not called)
  • isRestoring() is true if your context is recovering after being killed by Android
  • isResuming() is true if your context is “soft-resuming” as I call it, i.e. there was no call to onCreate() before going through onResume()
  • isApplicationBroughtToBackground(): sometimes it’s necessary to distinguish between your activity being paused by another activity of your own application, or by an entirely different application. This method yields true if another application’s activity is hiding yours.

Dialog helpers

BetterActivity offers the following helper methods to easily let you spawn dialogs:

  • showInfoDialog(): shows an alert dialog with an info icon
  • showAlertDialog(): shows an alert dialog with a warning icon
  • showErrorDialog(): same as alert dialog, but takes an exception as an argument
  • showListDialog(): shows a dialog with a list of Ts (T is some generic type). When clicking an entry, it will call back to a handler with the T that was selected.

all dialogs are customizable (e.g. message or icon).

There is more to come!

There’s a lot more in Droid-Fu at the moment (will cover that in upcoming posts), and there will be even more in the future, since I’m continually working on this library.

Cool, where can I get it?

The Droid-Fu source code is currently hosted on GitHub, which is the place where the cool kidz hang out these days. It’s a maven project, but the JARs aren’t yet hosted anywhere. Anyway, just check it out using git clone:

git clone git://github.com/kaeppler/droid-fu.git

and run:

mvn install -DcopyTo=path/to/your/apps/lib/dir

(you need to install git and maven2 for all that magic to work).

Happy coding!

About these ads

68 Comments »

  1. Is isApplicationBroughtToBackground() supposed to be part of BetterActivity? I couldn’t find that method browsing through the repository.

    Comment by Jonathan Holland — December 4, 2009 @ 4:22 pm

    • sorry, forgot to ‘git push’, it’s there now.

      One more note. If you don’t feel like inheriting from Better*Activity, e.g. because you only want to use this one method, you can also go through BetterActivityHelper, where it’s defined as a static method.

      Comment by Matthias Käppler — December 4, 2009 @ 4:42 pm

  2. Apache License, version 2.

    Comment by Matthias Käppler — December 4, 2009 @ 5:04 pm

  3. [...] I discourage anyone from using the code linked here. I’ve bundled a better solution with my Droid-Fu library, which is a little more intrusive, but leads to much leaner code for the application [...]

    Pingback by Android In-Sync: Handling concurrent tasks in Google Android « Brain Flush — December 15, 2009 @ 3:10 pm

  4. Thanks for the framework – I was able to get it working without subclassing BetterActivity. When I try to subclass BetterActivity I get an error – something along the lines that the window manager could not resolve the activity ..

    Comment by Alex Zivkovic — December 15, 2009 @ 5:41 pm

    • What do you mean with the window manager cannot resolve the activity? Do you mean the class loader tries to load the class and doesn’t find it? Are you deploying the JAR to the device/emulator along with your app?

      Comment by Matthias Käppler — December 15, 2009 @ 5:47 pm

      • Is there a place that I can send you a stack trace? I don’t see the window manager error, but when I do subclass BetterDefaultActivity I see this:
        Failure delivering result ResultInfo{who=null, request=999, result=-1, data=Intent { comp={my class} (has extras) }} to activity {my activity}: java.lang.IllegalArgumentException: Activity#onCreateDialog did not create a dialog for id 0

        When I don’t subclass BetterDefaultActivity it works fine.

        Comment by Alex Zivkovic — December 15, 2009 @ 9:50 pm

      • I have a hunch about this. Any chance that your activity is overriding onCreateDialog()? That method is defined in BetterDefaultActivity to render a progress dialog when you run a BetterAsyncTask. The ID for that dialog is 0 by default, and the after() handler tries to remove a progress dialog with that ID. When simply overriding that method, the dialog is never created so removing it fails.

        If you want to disable this behavior, just call disableDialog() on the BetterAsyncTask. Then you’re safe to do whatever you need in onCreateDialog().

        I’ll see if I can come up with a more flexible solution to this.

        Comment by Matthias Käppler — December 17, 2009 @ 10:41 am

  5. I have not used the library but while going thru the code I think that the progress dialogs are of concern. Imagine this scenario:

    User has started an BetterAsyncTask and has chosen to show a custom progress dialog.
    So the dialog is visible to the end user using the application
    Before the task completes, the user rotates the phone
    The activity that started the dialog is now no longer there so it will leak the dialog resource
    Moreover in onPostExecute() when it tries to close the dialog it will throw an exception as the current activity is not the owner of the dialog.

    Has anyone faced this issue yet?

    – Sanjay

    Comment by Sanjay — January 5, 2010 @ 10:04 am

    • That’s not correct. Better*Activity uses managed dialogs (onCreateDialog()), which are handled by Android. Upon activity exit the dialog will be removed and freed, and recreated upon restart. Moreover, BetterAsyncTask does nowhere hold references to these activity instances. Instead, the App object holds a map of weak references to these instances. Since no strong references to these instances are hold by any Droid-Fu object, they will be freed whenever the garbage collector sees fit.

      Comment by Matthias Käppler — January 5, 2010 @ 10:30 am

  6. Although I have not used the above said library, going thru its code indicates that there is a problem with the way progress dialogs are shown. Following is the scenario that shows what may happen:

    User starts a BetterAsyncTask and chooses to display a custom dialog.
    The task starts and displays the dialog as requested by the user.
    Before the task completes, the user changes orientation of the phone
    Now the dialog is not dismissed and hence it will leak
    Next issue – which is more serious – once the task finishes, when onPostExecute() gets called, it will try to execute activity.removeDialog(dialogId); – However no dialog is present so this will throw an exception.

    Let me know what you think.

    – Sanjay

    Comment by Sanjay Dandekar — January 5, 2010 @ 10:23 am

  7. I guess this is a double post.

    Again, this is not true. The very purpose of onCreateDialog() is to create managed dialogs, which are destroyed on activity exit and recreated on restart. Nothing is leaking here.

    As to removeDialog(). That’s also not true. First, if there should be no valid activiy instance upon task completion, the postExecute handler is simply skipped, hence removeDialog is not called. If removeDialog is called, then it is assured that there’s a valid activity instance.

    You will only see said exception when you carelessly overwrite onCreateDialog() without calling through to super(). Then, no dialog will be created on task start, but it will be removed on task end. I am aware of this issue and will iron that out in a forthcoming release.

    Comment by Matthias Käppler — January 5, 2010 @ 10:34 am

  8. Trying to implement BetterAsyncTask and I am gettting a little confused in its implementation. Are there any examples of it being used or JavaDoc?

    It seems as though you no longer use
    Result doInBackground(Params… params)
    but rather create a BetterAsyncTaskCallable to do the background operations?

    Also you use after(context, result) for the UI thread processing instead of onPostExecute(ReturnT result)?

    Comment by Stephen Kilsby — January 18, 2010 @ 6:34 am

    • Hey Stephen,

      you simply have to implement all abstract methods, that’s before(), doCheckedInBackground(), after() and handleError().

      You must NOT override on* methods, because that’s where BetterAsyncTask does its internal boiler plate work. I think I even declared those methods final, so you cannot override them anyway. But apart from different naming, you use these methods exactly as you would have used a normal AsyncTask.

      Comment by Matthias Käppler — January 18, 2010 @ 9:43 am

      • Thanks for clearing this up.

        Also is there nothing simliar to onPreExecute now?

        Have to say you’ve done well in creating and releasing this.

        Comment by Stephen Kilsby — January 19, 2010 @ 2:44 am

      • sorry, missed you said before() aswell.

        Comment by Stephen Kilsby — January 19, 2010 @ 3:06 am

  9. Forgive me again if im missing something but
    doCheckedInBackground
    is not an abstract method, and thus I am having problems overriding this. Any example code of it being used would be very helpful.

    Comment by Stephen Kilsby — January 19, 2010 @ 4:02 am

    • Finally got AsyncTasks working all fine.

      Looking at doCheckedInBackground in the javadoc rather than looking at the decompiled source of the jar helped.

      Comment by Stephen Kilsby — January 19, 2010 @ 4:34 am

      • Good :-)

        And you’re right, only handleError() is abstract, which is probably a little confusing. But note that all these APIs are still subject to change.

        I’ll extend the class API docs with a proper example.

        Comment by Matthias Käppler — January 19, 2010 @ 9:44 am

  10. Hi Matthias, thank you for your hard work on this Android package! I’m having a bit of trouble migrating from the old concurrency code you wrote to the new Droid-Fu stuff. Specifically, I’m getting this:
    Error: AndroidRuntime caused by android.content.res.Resources$NotFoundException: String resource ID #0x0

    when I try to task.execute();
    If I task.disableDialog(); first, my code works fine and the concurrency aspects are great! I suspect that I’m missing something with regard to how I’m supposed to set up progress bars / dialogs in Droid-Fu.

    I know that you’re already working on adding some examples to the API, but if you have any tips to nudge me in the right direction, I’d appreciate it! Thanks again!

    Comment by Joshua Hoffman — January 21, 2010 @ 1:31 am

    • As these things usually go, I struggled with the above off and on all week, and a few hours after I finally broke down and posted about it I fixed the error by doing the following:
      1. create a string resource.
      2. open the r.java file and look at the hex numbering of that resource.
      3. convert to decimal
      4. assign that decimal number to the dialog I am opening

      I suspect that there is a better way to do it than this, and I’d love to know what it is! Thanks again, and sorry to clutter up your comments!

      Comment by Joshua Hoffman — January 21, 2010 @ 3:41 am

      • Hi,

        I’m sorry you had to struggled with this. It’s one of the still undocumented parts of the library (mental note: write more JavaDoc).

        What you have to do is either define two string resources: droidfu_progress_dialog_title and droidfu_progress_dialog_message

        or you can call setProgressDialogTitleId() and setProgressDialogMessageId() on your BetterActivity instance.

        The problem here is that BetterAsyncTask automatically launches a managed progress dialog (unless you disabled that), but it doesn’t know what to use for the dialog title and body. To account for i18n, I decided that the user must either decide themselves which resources to use, or globally defined it using a resource ID Droid-Fu knows about.

        Comment by Matthias Käppler — January 21, 2010 @ 9:45 am

  11. A cool thing you can check out is the WeakAsyncTask class in the Android source code ( specifically the source of the Contacts App).

    Comment by Nikhil Sarda — February 4, 2010 @ 10:37 am

  12. I ran into an issue with BetterHttpResponse. The constructor calls getContent and getResponseBodyasString also calls getContent. So if you call getResponseBodyAsString at any time it will throw an IllegalStateException since getContent will have been called twice.

    Comment by Robert Pond — February 11, 2010 @ 6:11 pm

  13. Other than that fantastic library after I figured out how to use it hehe.

    Comment by Robert Pond — February 11, 2010 @ 6:12 pm

  14. Hello Matthias,

    I’ve extended Droid-Fu to support a new component, which I’ve called WebImageButton. It’s just the WebImageView, but instead of a ImageView to be one of the componentes of the ViewSwitcher, it’s a ImageButton.

    How can I send you a patch to you improve your library?

    Thanks

    Lucas.

    Comment by Lucas Rosada — March 1, 2010 @ 8:37 pm

    • Great, well, best would be by forking the project on GitHub, commiting your changes against the fork, and sending me a pull request. If you’re not using Git, you can just send me a patch if you like. As I’m not working on any Android stuff right now, it could take a while tho before I get to add it.

      Comment by Matthias Käppler — March 2, 2010 @ 9:42 am

  15. Great library, just plugging it in now.

    1. I’d like to use a BetterAsyncTask but with a non-interdetminate ProgressDialog (that I can update)
    So, Is it safe to override OnCreateDialog(int id) ?

    2. Is it safe to override onProgressUpdate(…) ?

    Cheers

    Rob

    Comment by Rob Shepherd — March 3, 2010 @ 3:19 pm

    • 1) it is, as long as you don’t call through to super() and tell Droid-Fu which dialog you want to show instead by calling task.useCustomDialog(yourDialogId);
      2) off the top of my head, I can’t think of a reason why you couldn’t

      sorry for the lack of documentation. I’m currently working on other projects, but will definitely get back to it.

      Comment by Matthias Käppler — March 3, 2010 @ 4:54 pm

  16. Hello Matthias,
    Thank you very much for this very useful library. I’m running into a small issue and wonder if you can point me in the right direction…When implementing WebImageView, everything displays like it should, but I’m getting the following warning:
    WARN/nalizableReferenceQueue(340): Could not load Finalizer in its own class loader. Loading Finalizer in the current class loader instead. As a result, you will not be able to garbage collect this class loader. To support reclaiming this class loader, either resolve the underlying issue, or move Google Collections to your system class path.
    WARN/nalizableReferenceQueue(340): java.io.FileNotFoundException: com/google/common/base/internal/Finalizer.class

    I’ve built the jar from source and tried the pre-built package with same results. My build path does include the droid-fu jar.

    Thanks,
    Tom

    Comment by Tom K. — March 3, 2010 @ 4:41 pm

    • It’s just a warning, nothing to worry about really. I comes out of the Google MapMaker class used in Droid-Fu. As far as I know there is only one class loader active in Android, so we don’t need to garbage collect it. I’ve profiled our App for excess memory consumption and couldn’t find any leaks related to that, so I suppose it’s not an issue.

      Comment by Matthias Käppler — March 3, 2010 @ 4:48 pm

      • OK. Thanks again!

        Comment by Tom K. — March 3, 2010 @ 5:01 pm

      • Matthias, you say it only is a warning, however I have application crashing after writing the aforementioned error into LogCat. Any suggestions?

        Thanks,

        Vladimir

        Comment by Vladimir Grichina — May 15, 2011 @ 5:05 pm

      • That would be an unrelated crash I guess. I’ve never seen our app crashing because of that warning.

        Comment by Matthias Käppler — May 16, 2011 @ 8:57 am

      • Yes, probably it was related to something else, cannot reproduce it anymore.

        Comment by Vladimir Grichina — May 17, 2011 @ 5:08 pm

  17. Hi Matthias,
    DroidFu has been doing wonders for us in our app.

    I’ve came up across some AsyncTask behavior I do not understand and was wondering if anyone here can explain it.

    When I try to cancel an BetterAsyncTask it does not seem to do anything (always returning false, since it couldn’t cancel the background thread).

    I have been trying to do my own cancel override, specifically setting a boolean for being cancelled and then not running after() in
    protected final void onPostExecute(ReturnT result)
    if it is cancelled.

    But when setting it to true on my task object; and then waiting for the background task to complete, the onPostExectue is being run in a different object from the original one I created and the boolean is always set to its initial false value. So I am finding it impossible to cancel a task.

    Hopefully you can all understand what I am trying to say and can give some insight on this(Why AsynTasks call complete on a different object than the one created).

    Comment by Stephen Kilsby — March 5, 2010 @ 1:28 am

    • Sorry,

      Actually It was my fault the entire time.

      Should always remember when something seems totally strange, its probably not.

      Cheers again for DroidFu….

      Comment by Stephen Kilsby — March 5, 2010 @ 5:36 am

  18. Hello Matthias,

    Thanks for your efforts in humanizing the Android development! :)

    I’ve looked through the source code and have come to the conclusion (please, correct me if I’m mistaken):

    If by the time the BetterAsyncTask has finished its job there’s no caller Activity (because it went to the background due to a phone call and was killed by OS, so a WeakReference to that Activity in DroidFuApplication has been automatically cleared by VM), then that Activity will never know the result of the BetterAsyncTask’s job (even if at some point later the Activity will be recreated, because user has finally finished his/her endless phone chatter, there’s no mecanism of passing of some pending result to the Activity). I also think this may result in the following bug – recreated Activity will also automatically restore its previous state including the progress popup, but since the popup most likely is non-cancellable the popup will stick here forever.

    Comment by Vit — April 11, 2010 @ 9:06 pm

  19. [...] projects so expect to hear more about this library on this blog.  For now, check out the developer’s website and read up on what he’s up [...]

    Pingback by Android Development Made Simpler with Droid-fu | DroidWeb — July 26, 2010 @ 5:04 pm

  20. I would tend to agree with Vit’s observations and would like to know if there is something I am missing.

    Comment by P — November 2, 2010 @ 10:13 pm

  21. Any good tutorials someplace??

    Comment by franc — November 10, 2010 @ 2:24 pm

  22. yep, more tutorials should be bettter…

    Comment by caker — December 1, 2010 @ 5:31 am

  23. Hi Matthias,
    I wanted to let you know that I am using ImageLoader and Caching in my new app, both modules rocks!

    Many thanks for this great work, you are a rockstar :)

    fyi everyone:
    I extended and added few more features
    – ObjectCaching: to store and share data objects between Activities and components
    I was using custom LocalStore before, using Cache works much better and faster

    I’ll be sharing custom extensions soon, hope this helps anyone interested

    Comment by WareNinja — December 12, 2010 @ 3:17 pm

    • awesome. I’m curious about the object cache, since we’re currently also working on one. are you on github?

      Comment by Matthias Käppler — December 13, 2010 @ 9:02 am

  24. I just realized that I forgot to reply, sorry for that.

    @Matthias: my space is @ https://github.com/wareninja

    The project I used & extended also some of your stuff is here
    -> https://github.com/wareninja/generic-store-for-android

    Comment by WareNinja — February 7, 2011 @ 1:32 pm

  25. Hi

    Thx for a realy nice library, i have a question though.
    I’m not that good when it comes to licenses and such, should a put a notice visible to the end user of a app that i use your library or is it enough to include the license in the source?

    Comment by Edvald — February 9, 2011 @ 12:11 pm

    • not even that, the Apache license is not viral. You just have to stick to its terms: don’t remove the license from Droid-Fu when you distribute it with your app, and if you should make changes to the library, do not remove copyright notices of the original authors. In general it’s a very liberal license, and a very short and concise one so don’t be afraid to actually read it (it’s actually quite legible, even if you don’t speak legalese).

      Comment by Matthias Käppler — February 9, 2011 @ 12:24 pm

      • oh and, while it’s certainly not a requirement, it’s always cool to mention droid-fu in your about screen :-) only if you feel comfortable about it of course.

        Comment by Matthias Käppler — February 9, 2011 @ 12:25 pm

  26. I totally agree with this too, mentioning also in about page is a nice way to show appreciation.

    check these screenshots as an example ;)

    -> http://dl.dropbox.com/u/13849473/aboutview2.png
    -> http://dl.dropbox.com/u/13849473/aboutview1.png

    Comment by WareNinja — February 9, 2011 @ 2:16 pm

  27. I see the mental note about more “write more Javadoc” got dropped by the wayside;) I am looking at Droid Fu, trying to figure out if I want to use it instead of AsyncTask in my own work, but I am finding the Javadoc, well, sparse.

    I am glad I found this wordpress blog on it, since this is a lot more info, but still: warts and all, AsyncTask is still better documented. In particular, I cannot find any reference to whether Droid Fu as a whole is just as applicable to recent versions, 2.2, 2.3 and even 3.0 as it was to the 1.6 that was current when it was developed.

    Comment by Matt J. — February 15, 2011 @ 6:08 am

    • Hi,

      I’m busy with other projects at the moment (first and foremost, our Android in Practice book), and this is not the only project I maintain. Please respect that I only have so much time. I invite everyone who already uses the library to contribute to the documentation.

      As to your question: BetterAsyncTask is just an AsyncTask that injects Context objects in all callbacks. Instead of onPreExecute and onPostExecute, you implement before() and after(). It will spawn a dialog by default, but you can disable that by calling disableDialog().

      Droid-Fu targets all Android versions up from 1.5. The primary goal of the project was to wrap the core APIs and add helper code around them, and these APIs change rarely, if at all. If there are differences between API levels, the library provides a wrapper call that uses reflection to route to the platform specific call. One such example is DiagnosticSupport.getAndroidId, but there’s others.

      Maybe it’s time to create a mailing list. I still don’t really consider Droid-Fu to be a true project, since I’m pretty much the only committer (although I have received a few contributions bu others), and I don’t have enough time at the moment to set up full documentation and a project website. Again, I invite everyone to help me out, I believe in the power of communities :-)

      Comment by Matthias Käppler — February 15, 2011 @ 10:17 am

  28. [...] Droid-Fu – Contains utility classes as well as some self-contained, ready to use Android components, all of which I consider useful for typical Android applications. Some of the areas for which Droid-Fu offers support classes include: application life-cycle, background tasks, HTTP messaging, (remote) image handling, custom adapters. Read more, here. [...]

    Pingback by Android Development Resources (SDK) « Null's Void — March 2, 2011 @ 4:31 pm

  29. I was wondering about this BetterAsyncTask problem… Couldn’t it just be remedied by using a sticky intent broadcast. Such that the Activity uses a locally registered broadcast receiver that has an intent filter explicitly looking for a sticky intent that will be broadcast by the AsyncTask once it’s done with its request. … just a thought.

    Comment by Ivan — March 2, 2011 @ 8:51 pm

  30. dear friends,
    can any one post BetterAsyncTask Tutorial or sample code how to use it?

    i am still not able to implement it. any help would be appreciated.

    Comment by Umar — May 1, 2011 @ 11:58 am

  31. I would love to use this, and I’ve followed all the steps:

    1. Clone repository
    2. Compile using mvn install
    3. Copy jar to lib
    4. Add lib to classpath
    5. Create application class that inherits from DroidFuApplication (no error)
    6. Reference application class in manifest

    But when I try to add a WebImageView to my layout, I have this error message: “Element com.github.droidfu.widgets.WebImageView is not allowed here.”

    Any ideas?

    Thanks

    Comment by Sydney — May 16, 2011 @ 2:04 am

  32. [...] подобных целей также есть библиотека droid-fu, у которой есть компонент WebImageView, которому просто [...]

    Pingback by WebView вместо ImageView | Prodroid — July 21, 2011 @ 12:24 pm

  33. Took a little while to get this compiled and running, you may want to update the dependencies to not require API9, I had to hard-reset maven-android-sdk-deployer back to the point before they dropped support for this version…

    Comment by Erik — September 14, 2011 @ 6:57 am

  34. Sorry, but Application instance is not guaranteedly alive during the entire app workflow. As with Activities it has its own life-cycle. Check my post about this on StackOverflow – http://stackoverflow.com/questions/708012/android-how-to-declare-global-variables/4642069#4642069

    Comment by Vitaliy Khudenko (@VitaliyKhudenko) — September 16, 2011 @ 10:47 am

  35. [...] docs (specifically for AsyncTask management stuff, and you might also want to check out Droid-Fu which is an excellent little utility library that helps, and goes much farther than this example, [...]

    Pingback by Android Application and AsyncTask basics | Android Xpress — October 26, 2011 @ 5:32 am

  36. [...] (안드로이드 멀티쓰레드에 대한 설명) http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterser… (AsyncTask 의 문제개선 소스 설명 및 배포) 2011.03.03 15:27:03 pulak [...]

    Pingback by AsyncTask 와 Handler 의 차이점 « 가짜해커 — November 6, 2011 @ 5:12 am

  37. For all those who are in need of sample code, check this out:

    http://code.google.com/p/edwardslab-android/source/browse/Mobile+Metagenomics/src/edwardslab/util/ResultView.java?spec=svn159&r=159

    Comment by sgali — December 8, 2011 @ 6:41 pm

  38. Great article! We will be linking to this particularly great article on our website. Keep up the great writing.

    Comment by خالد — March 22, 2012 @ 12:29 pm

  39. fedora vs ubuntu…

    [...]Introducing Droid-Fu for Android: BetterActivity, BetterService and BetterAsyncTask « Brain Flush[...]…

    Trackback by fedora vs ubuntu — April 6, 2012 @ 12:29 pm

  40. When I originally left a comment I seem to have clicked on the -Notify me when new comments are added- checkbox and now each time a comment is added I recieve four emails with the same comment. There has to be a way you can remove me from that service? Thank you!

    Comment by nanadroid — April 29, 2012 @ 1:59 pm

    • I checked everywhere in the post and dashboard settings, but there are no controls for comment users, just for the comments themselves. Sorry! Can you not just send them to spam? Or have you tried going back to the original posting and see if you can change it there?

      Comment by Matthias Käppler — April 30, 2012 @ 9:37 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 37 other followers

%d bloggers like this: