AndroidAnnotations, ou comment simplifier le dev Android

Disclaimer : étant l’auteur du framework AndroidAnnotations, je suis bien entendu d’une subjectivité à toute épreuve.

Amis développeurs Android, vous avez probablement remarqué à quel point le framework Android nécessite d’écrire du code dit d’infrastructure, ce qui vous prend du temps que vous pourriez consacrer à créer de la valeur métier, mais surtout de zoulies interfaces.

Quand vous débarquez du monde JEE, avec l’habitude de mettre des annotations partout et zouuuu ça fait tout tout seul, cela peut être un peu frustrant.

Oui mais voilà, vous a t’on gentiment expliqué, sur Android les annotations magiques c’est pas possible parce que ça nécessite de la réflexion, que la réflexion c’est leeent, et en plus le modèle de développement fonctionne beaucoup par héritage et ne vous permet pas de découpler votre code.

Beaucoup de bruit pour pas grand chose

Prenons un exemple simple : un vue contenant une champ texte et un bouton. Quand on clique sur le bouton, le contenu du champ texte est affiché en titre de l’activité, sous la forme “Hello X !” (X étant le contenu du champ texte). Bien entendu, la string doit être internationalisée.

En code, cela donne :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class MyActivity extends Activity {

    EditText myEditText;

    String helloFormat;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.myLayout);

        myEditText = (EditText) findViewById(R.id.myEditText);

        helloFormat = getString(R.string.helloFormat);

        View myButton = findViewById(R.id.myButton);
        myButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
              myButtonClicked();
            }
        });
    }

    void myButtonClicked() {
        String name = myEditText.getText().toString();
        setTitle(String.format(helloFormat, name));
    }
}

Moins de code = productivité accrue


AndroidAnnotations vous propose de générer le code d’infrastructure automatiquement à la compilation grâce à l’utilisation d’annotations dédiées et d’un annotation processor. Il adopte de plus le principe de convention over configuration pour les noms de ressources, ce qui diminue encore la quantité de code à écrire.

Dès lors, voici ce que devient l’exemple précédent :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Enhance(R.layout.myLayout)
public class MyActivity extends Activity {

    @ViewById
    EditText myEditText;

    @StringRes
    String helloFormat;

    @Click
    void myButtonClicked() {
        String name = myEditText.getText().toString();
        setTitle(String.format(helloFormat, name));
    }
}

Comment ça marche ?

En pratique, une sous classe de votre activité est générée à la compilation. Cette sous classe contient le code manquant correspondant aux annotations que vous avez utilisé. Côté performance, c’est exactement comme si vous écriviez le code à la main. Pas de réflexion !

Pour plus de détails sur le fonctionnement, il y a une page du wiki, mais aussi les sources.

What else?

Je ne vous ai présenté qu’une infime partie de ce que peut faire AndroidAnnotations. Pour en savoir plus, vous pouvez consulter la liste complète des annotations sur le svn, et lire la documentation.

Voici un exemple plus complet :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Sets the content view to R.layout.main
@Enhance(R.layout.main)
public class MyActivity extends Activity {

    // Other annotations available: @Transactional, @Extra, @SystemService, @ItemSelected, @LongItemClicked, @RoboGuice and much more!

    // Injects R.id.myTextView
    @ViewById(R.id.myTextView)
    TextView textView;

    // Injects R.id.myInput
    @ViewById
    EditText myInput;

    // Injects R.string.hello
    @StringRes(R.string.hello)
    String helloFormat;

    // Injects R.color.androidColor
    @ColorRes
    int androidColor;

    // Called when R.id.myButton is clicked
    @Click
    void myButton() {
         String name = myInput.getText().toString();
         doSomeBackgroundWork(name);
    }

    // Always executed in a background thread
    @Background
    void doSomeBackgroundWork(String name) {
         // Do some background work that should not freeze the UI
         String message = String.format(helloFormat, name);
         updateText(message);
         updateColorAfter5Secs();
    }

    // Always executed in the ui thread
    @UiThread
    void updateText(String message) {
         textView.setText(message);
    }

    // Always executed in the ui thread, with a delay of 5 seconds
    @UiThreadDelayed(5000)
    void updateColorAfter5Secs() {
         textView.setTextColor(androidColor);
    }
}
VN:R_U [1.9.22_1171]
Rating: 0 (from 0 votes)
Share

À propos de Pierre-Yves Ricau

Découvrez mon cv dynamique en ligne !
Ce contenu a été publié dans Android, avec comme mot(s)-clef(s) , , , , , , , , . Vous pouvez le mettre en favoris avec ce permalien.

5 réponses à AndroidAnnotations, ou comment simplifier le dev Android

  1. Je vois que mon article sur les annotation processors en Java t’a servi ;)

    Toujours pas de solution retenue pour éviter les templates de code stockés dans des String ?

    VN:R_U [1.9.22_1171]
    Rating: 0 (from 0 votes)
  2. Et non ! Ceci dit, maintenant, je gère les imports :-P

    Pour ceux qui s’interrogent sur le sens des propos cryptiques de Bastien, regardez donc comment fonctionne la partie génération de code… par exemple, l’instruction @UiThread.

    Une issue a été ouverte à ce sujet, libre à vous de proposer / implémenter une alternative ;-) .

    VN:R_U [1.9.22_1171]
    Rating: 0 (from 0 votes)
  3. jsoula@excilys.com dit :

    PY, T’aurais pas un article ou un benchmark sur les réels pbs de performance de la réflexion sur Android?

    VN:R_U [1.9.22_1171]
    Rating: 0 (from 0 votes)
  4. Et bien… non. Juste une impression générale, et des retours de devs aux débuts de RoboGuice. De plus, il est tout à fait possible que la donne ait changée avec l’arrivée d’Android 2.0.

    Comme d’habitude, le problème des benchmarks en Java c’est qu’il s’agit de microbenchmarks, et qu’on ne peut suffisamment isoler les paramètres. D’autant plus avec l’arrivée de JIT (Just In Time) sur Android 2.0 …

    Si quelqu’un veut se lancer la dedans, je suis sûr que ya matière à écrire un article polémique (ie attirant de la visite) ;-)

    VN:R_U [1.9.22_1171]
    Rating: 0 (from 0 votes)
  5. Ping : Android Annotations, des nouvelles du front ! | Excilys Labs

Laisser un commentaire