AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier...

36
Interface De Service Serviteur Client AIDL Android Interface Definition Language

Transcript of AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier...

Page 1: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

InterfaceDe

Service ServiteurClient

AIDLAndroid Interface Definition Language

Page 2: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

ServiteurClient

Process Process

IPC Inter Process Communication ….….. mais sur une même machine …. pas entre plusieurs machines

Service

IPC

Page 3: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Spécification AIDL (.aidl)

package com.example.aidl2kristof.api;

interface InterfaceDeService {

int premierService();int secondService();

}

<<interface>>InterfaceDeService

int premierService();int secondService();

<<package>>com.example.aidl2kristof.api

<<interface>>IInterface

<<package>>android.os

<<class>>Parcel

<<class>>Binder

<<interface>>IBinder

<<class>>Stub

int premierService();int secondService();

<<class>>Proxy

Type Interne

<<package>>android.content

<<interface>>ServiceConnection

Page 4: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

<<class>>Stub

int premierService();int secondService();<<interface>>

InterfaceDeServiceint premierService();int secondService();

<<class>>Proxy

Android MiddlewareAndroid IPC

Page 5: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

<<class>>Stub

int premierService();int secondService();<<interface>>

InterfaceDeServiceint premierService();int secondService();

<<class>>Proxy

Android MiddlewareAndroid IPC

ServiteurClient

Process Process

Page 6: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

<<class>>Stub

int premierService();int secondService();

<<interface>>InterfaceDeService

int premierService();int secondService();

<<class>>Proxy

Android MiddlewareAndroid IPC

Page 7: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Spécification de l'interface IDL

package com.kristofaidldemo.api;

import com.kristofaidldemo.api.MonParcelable;

interface InterfaceDeService {int unService();

MonParcelable mode1(in MonParcelable inParam);

MonParcelable mode2(out MonParcelable outParam);

MonParcelable mode3(inout MonParcelable inoutParam);

}

Il faut packager

On peut importer

Exemple simple

3 modes de passage de paramètres ( Parcelable ! ):

- in

Client → Serveur

- out

Client ← Serveur

- inout

Client ↔ Serveur

//Un Paramètre = ModeParam + TypeParam + NomParam

FichierInterfaceDeService.aidl

Page 8: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Spécification des Parcelables

(si nécessaire)

package com.kristofaidldemo.api;

parcelable MonParcelable;

Il faut packager

FichierMonParcelable.aidl

Ce parcelable a un intérêt seulement dans le cas d'utilisation de paramètres en mode in, out et inout.

Les paramètres de type primitifs ne peuvent être passé qu'en mode in (par défaut).

Page 9: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

package com.kristofaidldemo.api;

import android.os.Parcel;import android.os.Parcelable;

public class MonParcelable implements Parcelable {

//// Données "utiles" du Parcelable ...//private int d1;private String d2;

Page 10: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

//… MonParcelable ….suite //// Il faut fournir un constructeur par defaut !// Utilisé par l'infrastructure sous-jascente //

public MonParcelable() {this.d1 = 0;this.d2 = "";

}

//// Constructeur Facultatif//

public MonParcelable(int d1, String d2) {this.d1 = d1;this.d2 = d2;

}

Page 11: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

//… MonParcelable ….suite //// Getter/Setter en fonction de vos besoins... // ...mais c'est mieux !//

public int getD1() { return d1; }

public void setD1(int d1) { this.d1 = d1; }

public String getD2() { return d2; }

public void setD2(String d2) { this.d2 = d2;}

Page 12: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

//… MonParcelable ….suite //// describeContents() … il la faut, c'est comme ca !// cf JavaDoc:// Describe the kinds of special objects contained in// this Parcelable's marshalled representation.//// Returns : a bitmask indicating the set of special// object types marshalled by the Parcelable. ////  ??? Il la faut !//

@Overridepublic int describeContents() {

// TODO Auto-generated method stubreturn 0;

}

Page 13: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

//… MonParcelable ….suite /** Factory .... * * ... le nom " CREATOR " ....doit être ainsi ... */public static final Parcelable.Creator<MonParcelable> CREATOR = new Parcelable.Creator<MonParcelable>() {

public MonParcelable createFromParcel(Parcel in) {int v1 = in.readInt();String v2 = in.readString();return new MonParcelable(v1, v2);

}

public MonParcelable[] newArray(int size) {return new MonParcelable[size];

}};

Page 14: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet1ière Etape : Implementation des Parcelables

(si nécessaire)

FichierMonParcelable.java

//… MonParcelable ….suite

public void writeToParcel(Parcel outParcel, int arg1) { // Pour les paramètre en mode out et inout

outParcel.writeInt(d1); outParcel.writeString(d2);}

public void readFromParcel(Parcel in) {// Pour les paramètre en mode in

d1 = in.readInt(); d2 = in.readString();}

public String toString() {return

"MonParcelable [d1=" + d1 + ", d2=" + d2 + "]";}

}

Page 15: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet

Le compilateur AIDL …. va traduire ces AIDL en java ….

Page 16: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

package com.kristofaidldemo.coteserveur.lib;

import ...

//// Implémentation du "Serviteur" ... Objet qui rend // effectivement les services ...//

////Premiere Etape : //// On "fabrique" une classe d’implémentation qui dérive de la // classe android.app.Service//// En conséquence de cette dérivation, cela implique // l’implémentation de la méthode : public abstract Ibinder// onBind (Intent intent)//public class InterfaceDeServiceImpl extends Service {

Page 17: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

private static final String

TAG=com.kristofaidldemo.coteserveur.lib.InterfaceDeServiceImpl.class.getName();

//// Variable compteur.... pour illustrer le code métier..//private int compteur=0;

Page 18: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

//// Seconde Etape : // ----------------//// En conséquence de la dérivation de la classe Service par // la classe InterfaceDeServiceImpl, on implémenté la // méthode onBind (Intent intent)//// Comme on illustre ici l'offre d'un service AIDL, cette // méthode onBind // doit retourner un Binder de type InterfaceDeService.Stub // (nommé ici monBinder... cf ensuite) et implémentant // les services apparaissant dans l'interface// InterfaceDeService(.aidl).////public IBinder onBind(Intent intent) {

return monBinder;}

Page 19: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

private InterfaceDeService.Stub monBinder = new InterfaceDeService.Stub() {

//// Notez ici l’implémentation des services apparaissant// dans l'interface InterfaceDeService(.aidl). // ... c'est ici qu’apparaît le " code métier " du// fournisseur de service ...//public int unService() throws RemoteException {

//Log.d(TAG, "Execution de 'unService'.");

compteur++;return compteur;

}

Page 20: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

@Overridepublic MonParcelable mode1( // Illustation du mode in

MonParcelable inParam)throws RemoteException {

int v1=inParam.getD1();String v2=inParam.getD2();Log.d(TAG, " inParam (avant modif)= "+inParam);

inParam.setD1(compteur);inParam.setD2("From mode1="+v2);Log.d(TAG, " inParam (apres modif)= "+inParam);

MonParcelable res = new MonParcelable(666, "in parameter");

Log.d(TAG, " resultat = "+res);

return res;}

Page 21: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

@Overridepublic MonParcelable mode2( // Illustation du mode out

MonParcelable outParam)throws RemoteException {

int v1=outParam.getD1();String v2=outParam.getD2();outParam.setD1(compteur);outParam.setD2("From mode2="+v2);Log.d(TAG, " outParam (apres modif)= "+outParam);

MonParcelable res = new MonParcelable(667, "out parameter");

Log.d(TAG, " resultat = "+res);

return res;}

Page 22: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

@Overridepublic MonParcelable mode3(// Illustation du mode outin

MonParcelable inoutParam) throws RemoteException {

int v1=inoutParam.getD1();String v2=inoutParam.getD2();

inoutParam.setD1(compteur);inoutParam.setD2("From mode3="+v2);

MonParcelable res = new MonParcelable(668, "inout parameter");

return res;}

// fin de private InterfaceDeService.Stub monBinder = ...

Page 23: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

public void onCreate() {// Création du servicesuper.onCreate();

Log.d(TAG, "unService...");Utils.listRunningService(getApplicationContext());

Utils.showShortToast(this, "onCreate()... Création du service...");

new MonThread().start();}

Page 24: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

public void onDestroy() {super.onDestroy();// Destruction du service

Log.d(TAG, "unService...");Utils.listRunningService(getApplicationContext());

Utils.showShortToast(this, "onDestroy()... Destruction du service...");

}

Page 25: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur ...

public int onStartCommand(Intent intent, int flags, int startId)

{

Log.d(TAG, "unService...");Utils.listRunningService(getApplicationContext());

Utils.showShortToast(this, "onStartCommand()...");

return super.onStartCommand(intent, flags, startId);}

Page 26: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur … pour être complet :

package com.kristofaidldemo.coteserveur.lib;

import android.util.Log;

public class MonThread extends Thread {

private static final String TAG=...

private int pause=1000;

private int compteur=0 ;

Page 27: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur … pour être complet :

@Overridepublic void run() {

while(compteur<200){

compteur++;

Log.d(TAG, "MonThread["+compteur+"]");try {

Thread.sleep(pause);} catch (InterruptedException e) {}

}}

}

Page 28: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur … Concernant l'AndroidManifest

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.kristofaidldemo.coteserveur.lib" android:versionCode="1" android:versionName="1.0" >

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16" />

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name"

<service android:name="InterfaceDeServiceImpl" android:enabled="true" android:exported="true"

> <intent-filter>

<action android:name="com.kristofaidldemo.intent.service.ZeServiteur" /> </intent-filter> </service>

</application></manifest>

Page 29: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur … Concernant l'AndroidManifest

<service android:name=The name of the Service subclass that implements the

service. This should be a fully qualified class name (such as, "com.example.project.RoomService"). However, as a shorthand, if the first character of the name is a period (for example, ".RoomService"), it is appended to the package name specified in the <manifest> element.

android:enabled=Whether or not the service can be instantiated by the system — "true" if it can be, and "false" if not. The default value is "true".

android:exported=Whether or not components of other applications can invoke the service or interact with it — "true" if they can, and "false" if not. When the value is "false", only components of the same application or applications with the same user ID can start the service or bind to it.

>

Page 30: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet2nde Etape : Le coté Serveur … Concernant l'AndroidManifest

<intent-filter><action android:name="com.kristofaidldemo.intent.service.ZeServiteur" />

</intent-filter>

Le nom de l'Intent dont devra disposer tout composant souhaitant se conencter au Serveur

Page 31: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Le Client doit disposer d'une référence sur le Serveur :

private InterfaceDeService monServiteur;

Page 32: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Le Client doit disposer d'une « connexion » sur le Serveur :

// L'interface ServiceConnection appartient à l'API

private ServiceConnection maConnection = new ServiceConnection()

{public

void onServiceConnected(ComponentName arg0, IBinder arg1) {…}

public void onServiceDisconnected

(ComponentName arg0) {…}

}

Page 33: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Le Client doit disposer d'une « connexion » sur le Serveur avec :

//// La Méthode onServiceConnected (...) de l'interface // android.content.ServiceConnection//// Called when a connection to the Service has been established,// with the IBinder of the communication channel to the Service.//// cf API Docs//public void onServiceConnected

(ComponentName arg0, IBinder arg1) {

monServiteur = InterfaceDeService.Stub.asInterface(arg1);

}

Page 34: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Le Client doit disposer d'une « connexion » sur le Serveur avec :

//// La Methode onServiceDisconnected (...) de l'interface// android.content.ServiceConnection//// Called when a connection to the Service has been lost. This// typically happens when the process hosting the service has crashed// or been killed.//// cf API Docs//public void onServiceDisconnected

(ComponentName arg0) {

monServiteur = null;}

Page 35: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Une fois que le Client se sera lié au Serveur :

String intentString = "com.kristofaidldemo.intent.service.ZeServiteur";

// Nom de l'intent-filter du service apparaissant// dans l'AndroidManifest.xml coté serveur

Intent intent = new Intent(intentString) ;

boolean res = BindService(intent,

maConnection, Context.BIND_AUTO_CREATE);

Il n'aura plus qu'à « naturellement » interagir avec :

int res = monServiteur.unService();

Page 36: AIDL - UPJVExemple Complet 1ière Etape : Implementation des Parcelables (si nécessaire) Fichier MonParcelable.java MonParcelable ….suite // // describeContents() … il la faut,

Exemple Complet3nde Étape : Le coté Client

Le Client doit disposer d'une « connexion » sur le Serveur avec :

//// La Methode onServiceDisconnected (...) de l'interface// android.content.ServiceConnection//// Called when a connection to the Service has been lost. This// typically happens when the process hosting the service has crashed// or been killed.//// cf API Docs//public void onServiceDisconnected

(ComponentName arg0) {

monServiteur = null;}