Skip to content

Category archive for: Google

Déstresser en codant : des annotations à glisser dans les programmes Java

En développant, on est souvent amener à reprendre ou à être confronté :) au code d’autres personnes. Et il n’est pas rare de vouloir laisser un commentaire bien senti (ou totalement hypocrite) sur la qualité de ce code.

On peut aussi développer un bout de code et vouloir laisser un petit message à ceux qui tomberont sur ce code (pour expliquer les circonstances, atténuantes ou non, qui ont mené à ce programme).

Réjouissez-vous ! c’est possible, et de manière plus élégante qu’un simple commentaire java : avec des annotations.

Des annotations pour faire des commentaires
Parmi les annotations destinées à commenter le code, on trouve :

  • @AhaMoment
  • @LegacySucks
  • @Fail
  • @OhNoYouDidnt
  • @RTFM
  • @WTF

et le génial @BossMadeMeDoIt pour reporter la responsabilité sur son chef :).

Mais il y a aussi des annotations prenant des paramètres, par exemple (exemples issus du site) :

1@AnimalsHarmedDuringTheMaking(
2    number = 1,
3    animal = "hamster",
4    disclosure = "didn't feed Fermie for 2 days to finish this on time")
5public class ConstantTimePrimalityTest {

ou

1@ProbablyIllegalIn(number = 17, region = STATES)
2public Money extractFractionalPennies(Account account);

et

1@WrittenWhile("surfing Chatroulette")
2public interface You {
3  void spinRightRoundBabyRightRound(Me me);
4}

Des annotations pour générer des actions

En fournissant un agent à la jvm (option -javaagent:gag-agent.jar), vous pouvez aussi déclencher des comportements « particuliers » :

1@Roulette(
2    probability = 0.005,
3    exception = PayYourContractorException,
4    message = "Courtesy reminder")
5public Service getRockSolidService() {

lancera une exception avec une probabilité de 5 pour mille … bon, ça reste à utiliser avec des pincettes 😉
De son côté, l’annotation @Noop désactivera une méthode.

Et il y a encore plein d’autres annotations à explorer, jetez un coup d’oeil à la JavaDoc.

[ Google Annotations Gallery ]
[ La JavaDoc ]

Tutorial : Premier développement Google AppEngine avec Go

Update: Quelques modifications sont à prendre en compte suite à l’arrivée de la version 1 de Go (vous pouvez utiliser l’application gofix pour mettre à jour votre code et changer la version d’api de 3 à go1).

Le but de cet article est d’expliquer comment mettre en ligne une application AppEngine en Go.

Je ne vais pas m’étendre sur l’installation du SDK et sur la structure du langage :

Et en avant pour cette première application.

Développement d’un générateur de triangle de Sierpinski en Go

Ce programme tout bête utilise un algorithme binaire tout simple pour générer un triangle de Sierpinski dont la taille est paramétrable (paramètre passé en ligne de commande). Pour plus de détails, suivez les commentaires du programme.

1package main
2 
3import (
4  "fmt"
5  "strings"
6  "strconv"
7  "flag"
8  "os"
9)
10 
11func main() {
12  // Analyse de la ligne de commande
13  flag.Parse()
14 
15  // La variable chargée de stocker le nombre de lignes
16  // à afficher
17  var nbLignes int
18 
19  // Parsing des paramètres en ligne de commande
20  if flag.NArg() == 0 {
21    // Si pas d'arguments => 16 lignes
22    nbLignes = 16
23  } else {
24    // Sinon, on prend la valeur passée en paramètres
25    var err os.Error
26    nbLignes, err = strconv.Atoi(flag.Arg(0))
27    if err != nil {
28      fmt.Println(err)
29      os.Exit(1)
30    }
31  }
32 
33  // Algorithme d'affichage du triangle
34  for i:=0; i<=(nbLignes - 1); i++ {
35    // Padding pour redresser le triangle
36    fmt.Print(strings.Repeat(" ", nbLignes -i))
37 
38    // Construction d'une ligne
39    for j:=0;j<=i;j++ {
40      if ((^i & j) != 0) {
41        fmt.Print("  ")
42      } else {
43        fmt.Print(" *")
44      }
45    }
46    fmt.Print("\n")
47  }
48}

Exemple de triangle généré :

                 *
                * *
               *   *
              * * * *
             *       *
            * *     * *
           *   *   *   *
          * * * * * * * *
         *               *
        * *             * *
       *   *           *   *
      * * * *         * * * *
     *       *       *       *
    * *     * *     * *     * *
   *   *   *   *   *   *   *   *
  * * * * * * * * * * * * * * * *

Modification du code pour tourner sur GAE

Nous allons maintenant nous attaquer à la version Google AppEngine.

Tout d’abord, installez le SDK (passez par le site en anglais pour pouvoir télécharger le sdk : http://code.google.com/intl/en/appengine/downloads.html)

Un programme Google AppEngine se base sur le package http de Go pour mettre en place un handler de connexion.
Exemple:

1import "http"
2 
3func init() {
4    http.HandleFunc("/", handler)
5}
6 
7func handler(w http.ResponseWriter, r *http.Request) {
8  fmt.Fprint(w, "Hello");
9}

En première intention, nous allons faire un programme qui affiche un triangle de Sierpinski de 16 lignes, non paramétrable.
Il faudra alors :

  • Modifier le nom de package (le package main est réservé aux programmes individuels)
  • Ajouter une procédure init()
  • Modifier la méthode main en handler HTTP
  • Supprimer le code de paramétrage du nombre de lignes
  • Supprimer les imports inutilisés

Voici ce que ça donne :

1package handler
2 
3import (
4  "fmt"
5  "strings"
6  "net/http"
7)
8 
9func init() {
10  http.HandleFunc("/", handler)
11}
12 
13func handler(w http.ResponseWriter, r *http.Request) {
14  nbLignes := 16
15 
16  fmt.Fprint(w, "<html><pre>");
17 
18  // Algorithme d'affichage du triangle
19  for i:=0; i<=(nbLignes - 1); i++ {
20    // Padding pour redresser le triangle
21    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))
22 
23    // Construction d'une ligne
24    for j:=0;j<=i;j++ {
25      if ((^i & j) != 0) {
26        fmt.Fprint(w,"  ")
27      } else {
28        fmt.Fprint(w," *")
29      }
30    }
31    fmt.Fprint(w,"\n")
32  }
33 
34  fmt.Fprint(w, "</pre></html>");
35}

Publication de l’application sur Google AppEngine

Pour publier sur GAE, votre application doit respecter une arborescence du type :

1sierpinski/
2  app.yaml
3  sierpinski/
4    sierpinski.go

où app.yaml est le descripteur de l’application :

1application: sierpinski-go
2version: 1
3runtime: go
4api_version: go1
5 
6handlers:
7- url: /.*
8  script: _go_app

Les éléments à indiquer dans le fichier sont les suivants :

  • L’identifiant de l’application (que vous déclarez lors de l’enregistrement de l’application dans GAE)
  • La version de l’application (1 pour l’instant)
  • La version d’API de go à utiliser
  • Dans la partie handlers, il faut déclarer l’expression régulière servant à déclarer les pages devant être servies par le script; ici, toutes les pages

Si tout est ok, vous pouvez maintenant tester votre application :

1dev_appserver.py sierpinski/

Connectez votre navigateur sur http://localhost:8080 et vous devriez obtenir votre triangle :)

Dernière étape : la publication.

Lancez alors la commande :

1appcfg.py update sierpinski/

Après quelques secondes, votre application sera disponible sur GAE.

Le résultat :
[ http://sierpinski-go.appspot.com ]

Bonus : paramétrer le nombre de lignes à afficher

Pour se faire plaisir et pousser un peu plus le concept, ajoutons un paramètrage du nombre de lignes à afficher :

1package handler
2 
3import (
4  "fmt"
5  "strings"
6  "strconv"
7  "net/http"
8)
9 
10func init() {
11  http.HandleFunc("/", handler)
12}
13 
14func handler(w http.ResponseWriter, r *http.Request) {
15  // Nombre de lignes par défaut
16  nbLignes := 16
17 
18  // Parsing du nombre de ligne depuis l'url
19  nbLignesParam := r.FormValue("nbLignes")
20  if nbLignesParam != "" {
21    nbConv, err := strconv.Atoi(nbLignesParam)
22    if err == nil && nbConv <= 64 {
23      nbLignes = nbConv
24    }
25  }
26 
27  fmt.Fprint(w, "<html><pre>");
28 
29  for i:=0; i<=(nbLignes - 1); i++ {
30    // Padding pour redresser le triangle
31    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))
32 
33    // Construction d'une ligne
34    for j:=0;j<=i;j++ {
35      if ((^i & j) != 0) {
36        fmt.Fprint(w,"  ")
37      } else {
38        fmt.Fprint(w," *")
39      }
40    }
41    fmt.Fprint(w,"\n")
42  }
43 
44  fmt.Fprint(w, "</pre></html>");
45}

(peu de modifications : ajout de l’import strconv et parsing de l’url avec request.FormValue)

On redéploie !

1appcfg.py update sierpinski/

Si vous avez déjà déployé la version précédente, il faudra sélectionner la bonne version à publier dans la console appengine

Et voilà le résultat :
[ http://sierpinski-go.appspot.com/?nbLignes=64 ]

ou encore, la version 32 lignes :

                                 *
                                * *
                               *   *
                              * * * *
                             *       *
                            * *     * *
                           *   *   *   *
                          * * * * * * * *
                         *               *
                        * *             * *
                       *   *           *   *
                      * * * *         * * * *
                     *       *       *       *
                    * *     * *     * *     * *
                   *   *   *   *   *   *   *   *
                  * * * * * * * * * * * * * * * *
                 *                               *
                * *                             * *
               *   *                           *   *
              * * * *                         * * * *
             *       *                       *       *
            * *     * *                     * *     * *
           *   *   *   *                   *   *   *   *
          * * * * * * * *                 * * * * * * * *
         *               *               *               *
        * *             * *             * *             * *
       *   *           *   *           *   *           *   *
      * * * *         * * * *         * * * *         * * * *
     *       *       *       *       *       *       *       *
    * *     * *     * *     * *     * *     * *     * *     * *
   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

[ http://sierpinski-go.appspot.com/?nbLignes=32 ]

Une boîte de saisie de mot de passe toute bête sous Android

Juste un petit post rapide pour loguer le code d’un PasswordDialog sous Android.

Un petit aperçu de cette boîte toute bête :

1// Récupération des ressources
2LayoutInflater inflater= LayoutInflater.from(this);
3final View textEntryView = inflater.inflate(R.layout.password_dialog, null);
4 
5// Création du builder
6AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
7dialogBuilder.setTitle("Saisissez le mot de passe");
8dialogBuilder.setView(textEntryView);
9 
10// Ajout du gestionnaire d'événements
11dialogBuilder.setPositiveButton("Ok",
12 new DialogInterface.OnClickListener() {
13   @Override
14   public void onClick(DialogInterface dialog, int which) {
15     EditText passField = (EditText)
16        textEntryView.findViewById(R.id.passwordField); 
17     Toast.makeText(passField.getContext(),
18           "Le mot de passe est : " +
19              passField.getText().toString(),
20           Toast.LENGTH_SHORT).show();
21   }
22});
23dialogBuilder.setNegativeButton("Annuler", null);
24 
25// Activation
26dialogBuilder.show();    

Et la définition de la ressource utilisée (password_dialog.xml) :

1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout
4  android:layout_width="fill_parent"
5  android:layout_height="wrap_content"
6  android:orientation="vertical">
7 
8  <EditText
9    android:id="@+id/passwordField"
10    android:layout_height="100dp"
11    android:layout_width="fill_parent"
12    android:layout_marginLeft="20dp"
13    android:layout_marginRight="20dp"
14    android:maxHeight="100dp"
15    android:gravity="top|left"
16    android:password="true"
17  /> 
18</LinearLayout>

Et voilà, vous avez un PasswordDialog simple et fonctionnel.

Stacktraces distantes sous Android

Le développement d’applications mobiles introduit de nouvelles problématiques lors du débogage.
Parmi celles-ci, la mise en place d’un système de consultation des stacktraces à distance est un passage quasi obligé.

Heureusement, deux outils sont disponibles pour effectuer cette tâche facilement.

Android remote stacktrace

Cette première bibliothèque est simple à utiliser; elle nécessite cependant d’avoir un serveur à disposition pour héberger un script php fourni.

Ce script est chargé de gérer l’enregistrement de l’exception ou son envoi par mail (ou toute autre action que vous désirez prendre en charge).

La mise en place de ce système est très simple :

  • Installez la bibliothèque dans votre classpath
  • Modifiez votre fichier AndroidManifest.xml pour y faire figurer la ligne :
    1<uses-permission android:name="android.permission.INTERNET" />
  • Modifiez la méthode onCreate de votre activité pour y ajouter :
    1ExceptionHandler.register(this, "http://votre.serveur/votreChemin");

    (où votreChemin est le chemin du script php suivant)

  • Installez ce script php sur votre serveur et modifiez le pour qu’il enregistre les stacktraces dans un fichier ou vous les envoie par mail

Et c’est tout. Désormais, chaque exception non catchée générera un log ou un mail. Simple et efficace.

Cependant, la stacktrace seule est parfois un peu limitée. En effet, Android étant multi-terminal, certaines Exceptions peuvent n’apparaître que sur un terminal donné, il faut alors plus d’informations pour diagnostiquer le problème; c’est là qu’intervient ACRA.

ACRA

Le système de log d’ACRA n’est autre qu’un Google Spreadsheet. A chaque crash, une nouvelle ligne s’ajoute au document.

Cette ligne comprend de nombreux champs dont la stacktrace, mais aussi, le niveau d’API, le modèle du téléphone, la résolution de l’écran, etc … Tout ce qu’il faut pour diagnostiquer le problème !

D’autre part, ACRA est fortement paramétrable et vous permet de modifier les données remontées mais aussi de présenter un écran de saisie lors d’un crash :

Installation d’ACRA (cf. documentation):

Voici un résumé rapide des différentes étapes d’installation :

  • Téléchargez l’archive
  • Importez le fichier CrashReports-template.csv fourni dans Google Docs
  • Créez un formulaire dessus et copiez la valeur formkey
  • Ajoutez acra dans vos dépendances Eclipse
  • Ajoutez l’anotation @ReportsCrashes à la définition de votre sous-classe d’Application et passez la formKey en paramètre :
    1import org.acra.*;
    2import org.acra.annotation.*;
    3 
    4@ReportsCrashes(formKey = "dGVacG0ydVHnaNHjRjVTUTEtb3FPWGc6MQ")
    5public class MyApplication extends Application {
    6}
  • Surchargez la méthode onCreate() pour lancer l’initialisation d’ACRA :
    1@Override
    2public void onCreate() {
    3    // The following line triggers the initialization of ACRA
    4    ACRA.init(this);
    5    super.onCreate();
    6}
  • Donnez les droits d’accès à internet à votre application

Voilà, la prochaine fois que l’application crashera, vous aurez une nouvelle ligne dans votre Google spreadsheet !

App Inventor : le RAD arrive pour les téléphones Android

Voici un court teaser de App Inventor, une application permettant de construire graphiquement une application Android :

Le crédo de l’application : Tout le monde peut développer sous Android, cf :

To use App Inventor, you do not need to be a developer. App Inventor requires NO programming knowledge. This is because instead of writing code, you visually design the way the app looks and use blocks to specify the app’s behavior.

[ AppInventor ]