Sunday, July 25, 2010

Best of this Week Summary 19 July - 25 July 2010

Sunday, July 18, 2010

Best of this Week Summary 28 June - 18 July 2010

Wednesday, July 7, 2010

Android performance tips

All videos and slides from sessions during Google's I/O conference last May 2010 are available here.

I watched The world of ListView and Writing zippy Android apps. Below are the items that were most interesting to me. They are all Android performance related.

The world of ListView

  • 9:15: A View in Android costs about one or 2K of RAM

  • 16:55: Call notifyDataSetChanged() (from the UI thread) when something in your adapter has changed.

  • 18:27: getItemViewType() is used to make sure convertView is of the correct type in getView().

  • 19:06: Make sure getViewTypeCount never changes. Note that it doesn't hurt performance if you always return say 10 even if you only have 2 different view types returned by getItemViewType().

  • 30:13: Shows how to create a custom list selector in xml.

  • 40:40: android:smoothScrollbar to prevent scrollbar changing size. Especially useful for listviews with items of which height can differ greatly

  • 41:00: Use fill_parent instead of wrap_content in a ListView

  • 53:10: If refreshing the whole screen via notifyDataSetChanged() is too much of a performance hit, you can try to get the visible position and use getChildAt() to figure out what view to update. Example code for that is here.

  • 53:50: Use inflate(item, parent, false) to prevent relative layout attributes being ignored in a listview.

In general: don't try to outsmart the ListView by building your own caching, nor depend in any way on the order of getView(position) getting called.


Writing zippy Android apps

Zippy means non-janky which means sluggish, slow etc.
  • 08:00: example apk of how not to do things/see how stuff performs. Includes small Perl sqllite wrapper script to see how much is being read from sqlite

  • 15:00: read/writes I/O on emulator is a lot faster than on a real device

  • 19:00: An AsyncTask can get killed before it finishes, e.g if the user hits the Home key. If it's important that the task finishes, use IntentService.

  • 24:15: Profiling/tracing apps 'adb shell am profile ...' with the TraceView tool.

  • 47:00: handling rotation when you don't want to reload your heavy objects: usegetLastNonConfigurationInstance() and onRetainNonConfigurationInstance(). See the Android reference for more info.

  • 51:00: Think about using files instead of sqlite (if you have limited structured data for example)

Sunday, July 4, 2010

Lessons learned Wicket + Spring + Hibernate + Mod4J project

At a recent project we used the following tools & frameworks:


Below are a couple of lessons learned which I remembered to write down:

Wicket
  • In a ModalWindow you'd probably want to use a AjaxSubmitLink, not a SubmitLink, if you want to use modalWindow.setWindowClosedCallback(). See here for explanation.

  • ajaxrequesttarget.addComponent: addComponent name might be a bit confusing for beginners. It means "add the component to the list of components be re-rendered/refreshed".

  • An AjaxSubmitLink doesn't update the model when setDefaultFormProcessing() is set to false. Not totally illogical, but you still might run it to it when you don't expect it.

  • Here are tips to validate related fields. (In the original the example code is missing.)

  • AjaxSubmitLink: if you get a "Component-targetted feedback message was left unrendered. This could be because you are missing a FeedbackPanel on the page" warning in your Tomcat server console, it seems you have to tell in the onError() of the AjaxSubmitLink which feedback panel(s) you want to have updated.
    You get the warning even when you have feedback panels higher up in the tree of the (Base)Page. An example to update those panels could be:

    Component infoFeedback = getPage().get("infoPanel");
    target.addComponent(infoFeedback);
    Component warnFeedback = getPage().get("warningPanel");
    target.addComponent(warnFeedback);
    Component errorFeedback = getPage().get("errorPanel");
    target.addComponent(errorFeedback);

    This solution was inspired by these posts: post1, post2, post3, post4.

  • To show/hide any HTML markup block dynamically, just wrap it with a WebMarkupContainer. In the code create that wrapper and make it visible or not depending on your requirements:

    boolean makeVisible = false;
    WebMarkupContainer blockContainer = new WebMarkupContainer("blockWrapper");
    blockContainer.setVisible(makeVisible);
    add(blockContainer);


  • Sometimes you might get a popup when using a ModalWinow that says "Reloading this page will cause modal window to disappear" when you don't expect it. Check the logs/console, you might just got an exception in your app (after which Wicket tries to redirect to the error page, which causes the popup to show; at least that's my reasoning).

JUnit
  • If JUnit can't find the Spring context.xml in the resources directory, then you have to add the resources dir to your Build path

Mod4J
  • Does not really support LazyLoading so not very efficient for large "graphs" of data/dependencies. In those cases you could decide to skip the DTO layer and directly access the domain model.

  • The Maven plugin IAM in Eclipse can be turned off for the Mod4J models project in Eclipse, otherwise it runs twice: once by Mod4J features, once by Maven (plugin).