I. Le développement pour périphérique mobile c'est quoi ?▲
I-A. Un périphérique mobile c'est quoi ?▲
Avant de ce lancer dans le développement tête baissée, il faut se poser la question de savoir ce qu'est une application pour périphérique mobile. Et avant même cette question, il faut se demander ce qu'est un périphérique mobile.
Un périphérique mobile est un appareil qui par définition peut être déplacé. Ainsi à aucun moment nous ne pouvons nous appuyer sur un environnement fixe pour nos développements. De plus le périphérique mobile et souvent de taille réduite. Cette taille n'est pas seulement le fruit des avancées technologiques, mais également des compris dans la puissance de ces machines. Une dernière chose est à prendre en considération : le système d'exploitation disponible sur le périphérique. Aujourd'hui dans le monde Windows nous avons trois grands types d'OS disponible :
- Windows Embedded CE ;
- Windows XP Embedded ;
- Windows Mobile.
Dans cet article nous ne traiterons que du développement pour Windows Mobile. Cet OS se retrouve dans nos PDA et dans nos smartphones. Aujourd'hui ces périphériques ont atteint une puissance de calcul et une taille mémoire telles qu'ils sont capables de faire tourner des applications aussi diverses que variées. Ces applications vont de l'Outlook mobile jusqu'aux applications de navigation GPS. Dès lors, pourquoi ne pas tirer partie de cette puissance pour y déposer vos applications métiers et faire en sorte que vos collaborateurs aient toujours à portée de main les dernières informations sur les clients, les commandes et autre et cela sans avoir à allumer leurs ordinateurs portables qui sont vraiment trop gros pour le métro ;).
I-B. Considérations d'ordre général pour le développeur▲
Malgré notre enthousiasme de tout à l'heure, il y a quand même des différences entre un ordinateur portable et un smartphone. Le développement d'application visant les plateformes mobiles comme Windows Embedded et Windows Mobile doivent être extrêmement soignés et une considération toute particulière doit être portée sur la gestion de la mémoire. Oh la ! Que n'ai-je pas dit. Gérer la mémoire en .NET ? Pas besoin le Garbage Collector s'occupe de tout. Eh bien, messieurs les développeurs Dotnet, cela n'est pas tout à fait vrai. C'est vrai que le GC s'occupe d'une bonne partie de cette tâche ingrate, mais il reste de nombreuses façons de perdre des Ko de mémoires alors que l'on pourrait l'éviter. Un des exemples les plus frappants, mais également le moins bien connu et maitrisé reste l'utilisation de Dispose et l'implémentation de IDisposable. Il n'est pas question de rentrer dans les détails ici, ce n'est pas le but. Au-delà de l'appel à Dispose à chaque fois que nécessaire, la gestion de la mémoire passe également par le soin tout particulier à apporter à la gestion des collections et des objets. En effet à quoi sert d'instancier un tableau de 150 éléments si dans 90 % des cas vous n'en utiliser que 30 ? De même à quoi sert une classe quoi comporte 30 champs de type string si vous n'en utilisez que deux ?
Une autre chose est à prendre en compte dès le début du développement de votre application. Bien que le Framework .NET permette un « style » de développement quasi similaire entre le Compact Framework et le Framework habituel, un élément est extrêmement différent. Il s'agit de la conception de l'interface graphique et des conditions d'utilisation.
Au niveau de l'IHM il faut prendre en compte :
- un écran très petit : en effet il ne faut pas perdre de vue que vous développez une application pour écran d'une taille très réduite et que votre application sera manipulée par un stylet ou même un doigt ! ;
- pas de clavier/souris : Cela n'est pas complètement vrai, mais le clavier virtuel est beaucoup moins facile à utiliser et surtout il prend beaucoup de place sur l'application. Quant à la souris, elle est quasi inexistante.
À partir de cette constatation, il devient évident que votre interface graphique devra être la plus simple possible et que vous ne pouvez pas vous contenter de transférer l'IHM de votre application Winform sur le Compact Framework.
Au niveau des conditions d'utilisation, nous avons :
- pas de disque dur, mais une ROM : même si c'est un avantage en termes de rapidité, sa taille généralement petite fait que vous devez faire attention à la quantité de données générées par votre application ;
- fonctionne sur batterie : Eh oui ces petites bêtes fonctionnent sur batterie et on le sait tous l'utilisation intensive du processeur n'est pas bon pour la batterie. Allez on retourne optimiser nos algos. ;) ;
- moyens de communication variés : rien ne garantit que la connexion à votre serveur de synchronisation se fasse grâce au câble USB utilisé la première fois. Ainsi vous devez prendre en compte les différents moyens que l'utilisateur à de se connecter non seulement à Internet, mais également à son PC.
I-C. Un petit mot à propos de cet article▲
Cet article est le premier d'une série destiné à embrasser la totalité des facettes du développement d'application pour Windows Mobile.
II. Notre première application pour plateforme mobile pas à pas▲
Maintenant que les bases sont jetées et que nous sommes d'accord sur les objectifs et les contraintes de notre application, nous allons pouvoir nous lancer.
II-A. Création du projet de développement et première configuration▲
Afin de pouvoir tester notre application, il nous faudrait un de ces précieux périphériques mobiles. Or s'il fallait fournir un smartphone à chaque développeur, cela ne serait pas gérable. Heureusement encore une fois Visual Studio nous sommes la mise en mettant à notre disposition un émulateur de terminal. Cet émulateur prend charge plusieurs types de terminaux et est accessible après la création du projet.
La création d'un projet pour le compact Framework se fait de façon traditionnelle. Une fois le projet créé nous retrouvons la vue du designer graphique que nous connaissons, mais légèrement différente pour prendre en compte les spécificités de la plateforme visée. À ce stade nous avons donc notre squelette d'application de créé. Il ne reste plus qu'à construire notre application dessus.
II-B. Conception de l'interface graphique▲
Une fois n'est pas coutume, nous allons commencer par créer l'interface graphique de notre application. Que les architectes et les puristes du développement ne m'en tiennent pas rigueur, je vous le promets je ne le fais d'habitude ;).
Nous avons donc au départ cette vue du designer avec notre périphérique mobile représenté. Jetons-nous sans attendre dans la liste des composants disponibles.
Sans surprise le nombre de composants disponibles est bien moins élevé que celui du Framework .NET complet. (Sinon le CF ne s'appellerait pas le Compact Framework). Commençons par nous renseigner sur les contrôles de placement que, j'en suis sur, vous utilisez massivement dans vos applications afin de les rendre complètement insensibles au redimensionnement qu'elles peuvent subir. Seuls le panel et le tabpage sont disponibles. Du côté des contrôles habituels, nombreux sont ceux manquant à l'appel, mais les principaux sont présents. De plus n'oublions pas que nous sommes limités par la taille des écrans des périphériques mobiles et que ceux « manque » de contrôle est, en fait, assez salutaire.
Au niveau des composants, nous avons par contre de nombreux changements. Le composant HardwareButton permet d'intercepter par le code les appuis sur les boutons du périphérique autre que les « soft-keys ». Le composant InputPanel permet quant à lui de faire apparaitre un clavier virtuel facilitant la saisie de texte. Enfin le composant Notification permet de faire apparaitre une bulle d'aide sur le bureau.
Pour notre application nous allons avoir besoin de créer un menu et une ListBox sur notre formulaire de départ. Ce qui nous donne ceci :
Au niveau du code nous avons maintenant ceci :
private
void
listBoxLists_SelectedIndexChanged
(
object
sender,
EventArgs e)
{
// Ajouter le code de gestion de la sélection d'une liste
}
private
void
menuItemQuit_Click
(
object
sender,
EventArgs e)
{
Application.
Exit
(
);
}
Jusque là le développement de notre application pour Windows Mobile ressemble fort au développement d'une application winform. En effet le principe reste le même et le compact Framework reste en tout point fidèle à l'esprit de simplicité de son grand frère. La seule différence notable entre les deux mondes est que le fait de cliquer sur la croix en haut à droite de la fenêtre principale ne ferme pas le programme. Il faut donc explicitement appeler Application.Exit() ou this.Close() pour que le programme soit fermé.
Nous allons maintenant rajouter un formulaire qui nous permettra d'afficher le détail de la liste de course et de cocher les lignes qui sont faites.
L'ajout d'un nouveau formulaire dans notre application ne pose en soit aucun problème. Il suffit de faire un clic droit sur le projet et de choisir Ajouter -> Winform. Passons maintenant à l'ajout de notre liste pouvant être coché. Un composant bien pratique en Winform est la CheckedListBox. Mais ce contrôle n'existe pas dans le compact Framework ! Il fait partie des classes qui n'ont pas été jugé essentielles et qui ont été retirés pour réduire l'empreinte mémoire du CF.
Mais qu'à cela ne tienne nous allons redévelopper notre propre CheckedListBox. Pour ce faire, et parce que nous sommes des gens organisés et méticuleux, nous allons créer un projet de type Libriairie de contrôle utilisateur. Pour faire cela il vous retourner dans l'assistant de création d'un nouveau projet et rechoisir « SmartDevice projet ». À l'écran suivant, il ne reste plus qu'à choisir le type de projet « Librairie de contrôles ».
Une fois ce nouveau projet créé il ne reste plus qu'à ajouter notre code.
public
partial
class
CustomCheckedListBox :
UserControl
{
private
CustomCheckedListBoxCollection items;
public
CustomCheckedListBox
(
)
{
InitializeComponent
(
);
this
.
items =
new
CustomCheckedListBoxCollection
(
this
);
}
public
CustomCheckedListBoxCollection Items
{
get
{
return
this
.
items;
}
set
{
this
.
items =
value
;
}
}
public
class
CustomCheckedListBoxCollection :
ICollection<
string
>
{
private
Dictionary<
string
,
CheckBox>
items;
private
CustomCheckedListBox cclb;
private
CustomCheckedListBoxCollection
(
)
{
this
.
items =
new
Dictionary<
string
,
CheckBox>(
);
}
internal
CustomCheckedListBoxCollection
(
CustomCheckedListBox cclb)
:
this
(
)
{
this
.
cclb =
cclb;
}
#region ICollection<string> Members
public
void
Add
(
string
item)
{
CheckBox cb =
CreateCheckBox
(
item);
this
.
cclb.
Controls.
Add
(
cb);
this
.
items.
Add
(
item,
cb);
}
public
void
Clear
(
)
{
this
.
items.
Clear
(
);
this
.
cclb.
Controls.
Clear
(
);
}
public
bool
Contains
(
string
item)
{
return
this
.
items.
ContainsKey
(
item);
}
public
void
CopyTo
(
string
[]
array,
int
arrayIndex)
{
throw
new
NotImplementedException
(
);
}
public
int
Count
{
get
{
return
this
.
items.
Count;
}
}
public
bool
IsReadOnly
{
get
{
return
this
.
cclb.
Enabled;
}
}
public
bool
Remove
(
string
item)
{
if
(
this
.
items.
ContainsKey
(
item))
{
this
.
cclb.
Controls.
Remove
(
items[
item]
);
return
this
.
items.
Remove
(
item);
}
else
return
false
;
}
#endregion
#region IEnumerable<string> Members
public
IEnumerator<
string
>
GetEnumerator
(
)
{
return
this
.
items.
Keys.
GetEnumerator
(
);
}
#endregion
#region IEnumerable Members
System.
Collections.
IEnumerator System.
Collections.
IEnumerable.
GetEnumerator
(
)
{
throw
new
NotImplementedException
(
);
}
#endregion
private
CheckBox CreateCheckBox
(
string
item)
{
CheckBox cb =
new
CheckBox
(
);
cb.
Dock =
DockStyle.
Top;
cb.
Text =
item;
return
cb;
}
}
}
Il ne reste plus qu'à faire les branchements dans la fenêtre principale :
public
partial
class
MainForm :
Form
{
public
MainForm
(
)
{
InitializeComponent
(
);
//Initialisation de Debug
for
(
int
i =
0
;
i <
5
;
i++
)
this
.
listBoxLists.
Items.
Add
(
"Liste "
+
i.
ToString
(
));
}
private
void
listBoxLists_SelectedIndexChanged
(
object
sender,
EventArgs e)
{
using
(
ListeDetailForm ldf =
new
ListeDetailForm
(
))
{
ldf.
ShowDialog
(
);
}
}
private
void
menuItemQuit_Click
(
object
sender,
EventArgs e)
{
Application.
Exit
(
);
}
}
Si vous avez étudié attentivement ce morceau de code, une chose a dû vous sauter aux yeux. L'instanciation de ListeDetailForm est encadrée par des using. Cette simplification d'écriture du C# permet d'être sûr que, quelle que soit la façon dont les instructions qui sont encadrées par le using{} sont exécutées, la méthode Dispose sur notre élément ListeDetailForm sera appelée. La libération des ressources non managées créées lors de l'affichage de fenêtre est un des points auxquels il faut faire attention sur les périphériques mobiles et la directive using() {} est parfaite pour ça.
II-C. Et sous le capot que mettons-nous ?▲
Maintenant que nous avons l'interface graphique, il est tant d'en faire quelque chose. Nous allons donc créer les objets « métier » dont nous avons besoin ainsi que certaines classes de filtrage.
Je vous invite à vous référer au code afin d'avoir le code complet des classes de support. Sachez seulement que 98 % du code reste le même entre ce que vous avez l'habitude de développer et un projet pour Windows Mobile.
Passons juste rapidement à la classe de filtrage.
public
class
IngredientView
{
public
List<
ListCourse>
ListContain
(
Ingredient ingredient,
List<
ListCourse>
listes)
{
var
selected =
from
liste in
listes where
liste.
Ingredients.
Contains
(
ingredient) select
ingredient;
return
selected.
ToList
(
);
}
}
Et là magie ! Nous retrouvons ce bon jeune Linq To Object. En effet Linq a été porté (ou plus exactement il n'a pas été supprimé) sur le CF. Cela nous prouve encore une fois que bon nombre des améliorations du Framework sont répercutées sur le CF. D'ailleurs l'évolution du C# est présente également, car nous bénéficions pleinement des derniers ajouts du C# 3.0 à l'exception de WPF.
III. Déploiement de notre application sur les périphériques mobiles▲
Maintenant que nous avons une application qui fonctionne très bien avec l'émulateur, il nous faut prévoir de quoi la transférer sur périphérique mobile. Cette manipulation se fait par le biais d'un fichier archive cab. Encore une fois Visual Studio est la pour nous simplifier la tâche.
Le déploiement d'application pour Smart Device se fait généralement grâce à des packages CAB (Cabinet file). Visual Studio possède un type de projet appelé « Smart Device cab project ». Ce projet vous permet de générer automatiquement un .cab contenant les fichiers nécessaires au déploiement de l'application. Pour les utilisateurs habituels Visual Studio, ce projet de setup est identique aux autres projets setup de Visual Studio, mais là encore en version « lite ».
Une fois ce projet créé il faut choisir ce qui sera déployé dans le setup. Vous pouvez faire cela en faisant un clic droit sur le projet de déploiement et choisir « Add ». Une fois la sortie principale ajoutée dans le projet de setup vous pouvez ajouter un raccourci dans le menu « Programme » de l'appareil. Pour ce faire il faut d'abord rajouter le dossier « Start menu folder » dans la liste du « File System » en faisant un clic droit sur le « File System ».
IV. Un petit mot sur la documentation du CF▲
Vous trouverez la documentation sur les classes disponibles dans le CF sur la MSDN ou dans la documentation du Framework installé sur votre poste de développement.
V. Conclusion sur cette introduction▲
À travers cette introduction nous avons vu que le développement d'application pour Windows Mobile à l'aide du Compact Framework est très proche du développement d'application Winform. En effet le CF permet de garder un « style » de programmation identique à celui de son grand frère. Le langage est le même, les classes de base sont les mêmes, et la plupart des fonctionnalités du framework sont présentes. Les grosses différences sont dans le nombre de classes disponibles et dans la façon de concevoir l'interface graphique. Ce ne sont pas les problèmes habituels qui vont nous poser problème, mais le développement pour périphérique mobile implique d'autres problèmes comme la synchronisation des données entre le périphérique et les serveurs ou simplement le PC maitre.
Ces points seront développés dans un prochain article qui portera sur SqlSever CE et WCF pour la synchronisation de données.
VI. Remerciements▲
Je tiens à remercier toute l'équipe dotnet pour leur aide et leurs conseils
Je remercie également RideKick pour sa relecture.
VII. Téléchargement▲
Les sources du début du projet « Liste De Courses » : c'est par iciici