Archives par mot-clé : Best practice

Les meilleurs pratiques

My life with Android: « it’s complicated »

Facebook screenshot: relationship status: it's complicated

Mobile development is difficult: there is not much memory, the CPU is low, network connection is limited, there are different screen sizes and hardware capabilities to take care of, etc. Android aims at helping on these topics, but the life of an Android developer is still not a paradise…

Some classes pretend to help, but just don’t

The framework encourages you to use classes that supposely simplify complex development.

For instance, AsyncTask « allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. »

However, there are limitations or other problems virtually impossible to solve. For instance with AsyncTask, the application crash when the orientation is changed.

Activity has leaked window PhoneWindow$DecorView that was originally added here 
E/WindowManager(  244):

Eventually, I have found that only services can correctly handle long running operations. But they are more complicated to code.

The XML nightmare

With XML, you can build a software that perfectly compiles, and crash at runtime. Sometime not entering in your own code at all.

In the worse situation, it can crash the OS without letting a second to run a debugger. For instance, when I was going to Settings > Account and Sync > Add account, the phone crashed and rebooted. Why? Because I forgot the smallIcon attribute in the authentificator.xml (similar to this Resources$NotFoundException: String resource ID #0x0).

The recycling in adapters

A ListAdapter connects data to rows representing this data in a ListView. As I already mentioned, resources are limited, so it is a good practice to recycle a former view rather than creating a new one. As such, when the user scrolls down the list, instead of creating new views for the new rows, the views are recycled from rows that are not visible anymore. This is usually performed with this nippet of code:

  1. if (convertView == null) {
  2.             view = mInflater.inflate(R.layout.mylayout, parent, false);
  3.         } else {
  4.             view = convertView;
  5.         }

But this can lead to strange beahaviours or things difficult to debug. For instance, if a list view has a checkbox, this code is incorrect

  1. checkBox.setChecked(myDataItem.isActve);
  2. checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  3. @Override
  4. public void onCheckedChanged(CompoundButton buttonView,
  5. boolean isChecked) {
  6. myDataItem.isActive = isChecked)
  7. }
  8. });

With this code, the checkboxes are checking and unchecking themselves randomly when the user scrolls the list. Whereas this code is correct. Can you spot the difference and explain what happens?

  1. checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  2. @Override
  3. public void onCheckedChanged(CompoundButton buttonView,
  4. boolean isChecked) {
  5. myDataItem.isActive = isChecked)
  6. }
  7. });
  8. checkBox.setChecked(myDataItem.isActve);

In the first case setChecked() triggers the onClickListener defined in a a data element which is now hidden.

SyncAdapter requires AccountAuthentificator and ContentProvider

A SyncAdapter is used to synchronize Internet data with a ContentProvider. This is what gives you a synchronized address book, a synchronized list of emails, synchronized tweets, etc.

In all this examples, it is require to provide an AccountAuthentificator. However, I think this account authentificator is irrelevant for synchronizing public data, like weather forecast.

Well, the android framework thinks differently. It is mandatory to have these 3 pieces: SyncAdapter, AccountAuthentificator, ContentProvider. If one is missing, the android system might crash when you go in the Settings screen, and the phone will reboot without little to no debug message:

EXCEPTION IN SYSTEM PROCESS.  System will crash.
E AndroidRuntime: java.lang.NullPointerException

If you think this one sucks too, please star issue 5009.

Best practice for changing the value of a column in SharePoint

In SharePoint development, it is pretty common to change the value of an element.

For instance, let’s consider the column named « Title » defined in many lists. Suppose we want to change the « Title » of an item. What’s sound straightforward is to write this

SPListItem item // get the needed item
item["Title"] = "New value";

Now to deply this solution on a French platform, and c’est le drame: Value does not fall withinh the expected range. That’s because the column is referenced here by its display name. So, for the French platform it should be

item["Titre"] = "New value";

Even worse. The display name is editable by end users (or more precisely by site administrators). Everyone get the point: this is code snippet is a worse practice.

The best practice is to use the internal name (which is « Title » for any language and will never change)

item[item.Fields.GetFieldByInternalName("Title").Id] = "New value";

And now, I can confidently say that SharePoint happy is developper unfriendly.

Note also, this sugguests another best practice: when you create a custom column: don’t use spaces in the internal name.

Google calendar/maps tip

Quand on crée un évènement dans Gogole calendar, et que l’on indique sa location pour avoir un lien sur Google maps, il faut placer l’adresse (comme 55 rue du faubourg saint honoré) ou bien un lieu connu (comme Tour Eiffel).

Maintenant, si le lieu n’est pas connu par Google (et c’est le cas pour le palais de l’Elysées, ou chez mes amis) je viens de découvrir que l’on pouvait ajouter une description à l’adresse. La syntaxe est la suivante (et pas géniale à mon avis):

55 rue du faubourg Saint-Honoré, Paris, France (Palais de l’Elysées)