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) :

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

ou

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

et

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

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 » :

@Roulette(
    probability = 0.005,
    exception = PayYourContractorException,
    message = "Courtesy reminder")
public 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.

package main

import (
  "fmt"
  "strings"
  "strconv"
  "flag"
  "os"
)

func main() {
  // Analyse de la ligne de commande
  flag.Parse()

  // La variable chargée de stocker le nombre de lignes
  // à afficher
  var nbLignes int

  // Parsing des paramètres en ligne de commande
  if flag.NArg() == 0 {
    // Si pas d'arguments => 16 lignes
    nbLignes = 16
  } else {
    // Sinon, on prend la valeur passée en paramètres
    var err os.Error
    nbLignes, err = strconv.Atoi(flag.Arg(0))
    if err != nil {
      fmt.Println(err)
      os.Exit(1)
    }
  }

  // Algorithme d'affichage du triangle
  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Print(strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Print("  ")
      } else {
        fmt.Print(" *")
      }
    }
    fmt.Print("\n")
  }
}

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:

import "http"

func init() {
    http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprint(w, "Hello");
}

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 :

package handler

import (
  "fmt"
  "strings"
  "net/http"
)

func init() {
  http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  nbLignes := 16

  fmt.Fprint(w, "<html><pre>");

  // Algorithme d'affichage du triangle
  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Fprint(w,"  ")
      } else {
        fmt.Fprint(w," *")
      }
    }
    fmt.Fprint(w,"\n")
  }

  fmt.Fprint(w, "</pre></html>");
}

Publication de l’application sur Google AppEngine

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

sierpinski/
  app.yaml
  sierpinski/
    sierpinski.go

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

application: sierpinski-go
version: 1
runtime: go
api_version: go1

handlers:
- url: /.*
  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 :

dev_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 :

appcfg.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 :

package handler

import (
  "fmt"
  "strings"
  "strconv"
  "net/http"
)

func init() {
  http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
  // Nombre de lignes par défaut
  nbLignes := 16

  // Parsing du nombre de ligne depuis l'url
  nbLignesParam := r.FormValue("nbLignes")
  if nbLignesParam != "" {
    nbConv, err := strconv.Atoi(nbLignesParam)
    if err == nil && nbConv <= 64 {
      nbLignes = nbConv
    }
  }

  fmt.Fprint(w, "<html><pre>");

  for i:=0; i<=(nbLignes - 1); i++ {
    // Padding pour redresser le triangle
    fmt.Fprint(w, strings.Repeat(" ", nbLignes -i))

    // Construction d'une ligne
    for j:=0;j<=i;j++ {
      if ((^i & j) != 0) {
        fmt.Fprint(w,"  ")
      } else {
        fmt.Fprint(w," *")
      }
    }
    fmt.Fprint(w,"\n")
  }

  fmt.Fprint(w, "</pre></html>");
}

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

On redéploie !

appcfg.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 :

// Récupération des ressources
LayoutInflater inflater= LayoutInflater.from(this);
final View textEntryView = inflater.inflate(R.layout.password_dialog, null);

// Création du builder
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("Saisissez le mot de passe");
dialogBuilder.setView(textEntryView);

// Ajout du gestionnaire d'événements
dialogBuilder.setPositiveButton("Ok",
 new DialogInterface.OnClickListener() {
   @Override
   public void onClick(DialogInterface dialog, int which) {
     EditText passField = (EditText)
        textEntryView.findViewById(R.id.passwordField);  
     Toast.makeText(passField.getContext(), 
           "Le mot de passe est : " + 
              passField.getText().toString(), 
           Toast.LENGTH_SHORT).show();
   }
});
dialogBuilder.setNegativeButton("Annuler", null);

// Activation
dialogBuilder.show();			

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">

  <EditText
    android:id="@+id/passwordField"
    android:layout_height="100dp"
    android:layout_width="fill_parent"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:maxHeight="100dp"
    android:gravity="top|left"
    android:password="true"
  />  
</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 :
    <uses-permission android:name="android.permission.INTERNET" />
    
  • Modifiez la méthode onCreate de votre activité pour y ajouter :
    ExceptionHandler.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 :
        import org.acra.*;
        import org.acra.annotation.*;
    
        @ReportsCrashes(formKey = "dGVacG0ydVHnaNHjRjVTUTEtb3FPWGc6MQ")
        public class MyApplication extends Application {
        }
    
  • Surchargez la méthode onCreate() pour lancer l’initialisation d’ACRA :
        @Override
        public void onCreate() {
            // The following line triggers the initialization of ACRA
            ACRA.init(this);
            super.onCreate();
        }
    
  • 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 ]