image/svg+xml $ $ ing$ ing$ ces$ ces$ Res Res ea ea Res->ea ou ou Res->ou r r ea->r ch ch ea->ch r->ces$ r->ch ch->$ ch->ing$ T T T->ea ou->r

Connexion à un service

Cycle de vie d'un service

Cycle de vie d'un service

Source

AIDL

Utilisation de AIDL

Langage AIDL

Parcelable

Une bibliothèque matricielle

Classe Matrix serialisable dans un Parcel

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.matrixlibrary;

import java.util.Arrays;

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

/* A matrix of integers */
public class Matrix implements Parcelable
{
	private final int rows, cols;
	private final int[][] content;
	
	public Matrix(int rows, int cols)
	{
		this.rows = rows; this.cols = cols;
		this.content = new int[rows][];
		// Initialize the matrix
		for (int i = 0; i < rows; i++) this.content[i] = new int[cols];
	}
	
	public static Matrix createIdentity(int n)
	{
		Matrix m = new Matrix(n, n);
		for (int i = 0; i < n; i++) m.set(i, i, 1);
		return m;
	}
	
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public int get(int i, int j) { return content[i][j]; }
	public void set(int i, int j, int value) { content[i][j] = value; }
	
	@Override public int describeContents()  { return 0; }

	@Override
	public void writeToParcel(Parcel dest, int flags) 
	{
		dest.writeInt(rows);
		dest.writeInt(cols);
		// Write the matrix row by row
		for (int i = 0; i < rows; i++)
			for (int j = 0; j < cols; j++)
				dest.writeInt(content[i][j]);
	}
	
	public static final Creator<Matrix> CREATOR =
		new Creator<Matrix>()
		{
			@Override
			public Matrix createFromParcel(Parcel source) 
			{
				int rows = source.readInt(), cols = source.readInt();
				Matrix m = new Matrix(rows, cols);
				for (int i = 0; i < rows; i++)
					for (int j = 0; j < cols; j++)
						m.set(i, j, source.readInt());
				return m;
			}

			@Override
			public Matrix[] newArray(int size) 
			{
				return new Matrix[size];
			}
		};

	@Override
	public String toString()
	{
		return Arrays.deepToString(content);
	}
}

En-tête AIDL pour la classe Matrix

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.matrixlibrary;

import java.util.Arrays;

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

/* A matrix of integers */
public class Matrix implements Parcelable
{
	private final int rows, cols;
	private final int[][] content;
	
	public Matrix(int rows, int cols)
	{
		this.rows = rows; this.cols = cols;
		this.content = new int[rows][];
		// Initialize the matrix
		for (int i = 0; i < rows; i++) this.content[i] = new int[cols];
	}
	
	public static Matrix createIdentity(int n)
	{
		Matrix m = new Matrix(n, n);
		for (int i = 0; i < n; i++) m.set(i, i, 1);
		return m;
	}
	
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public int get(int i, int j) { return content[i][j]; }
	public void set(int i, int j, int value) { content[i][j] = value; }
	
	@Override public int describeContents()  { return 0; }

	@Override
	public void writeToParcel(Parcel dest, int flags) 
	{
		dest.writeInt(rows);
		dest.writeInt(cols);
		// Write the matrix row by row
		for (int i = 0; i < rows; i++)
			for (int j = 0; j < cols; j++)
				dest.writeInt(content[i][j]);
	}
	
	public static final Creator<Matrix> CREATOR =
		new Creator<Matrix>()
		{
			@Override
			public Matrix createFromParcel(Parcel source) 
			{
				int rows = source.readInt(), cols = source.readInt();
				Matrix m = new Matrix(rows, cols);
				for (int i = 0; i < rows; i++)
					for (int j = 0; j < cols; j++)
						m.set(i, j, source.readInt());
				return m;
			}

			@Override
			public Matrix[] newArray(int size) 
			{
				return new Matrix[size];
			}
		};

	@Override
	public String toString()
	{
		return Arrays.deepToString(content);
	}
}

Définition AIDL pour un service de multiplication matricielle

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.matrixlibrary;

import java.util.Arrays;

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

/* A matrix of integers */
public class Matrix implements Parcelable
{
	private final int rows, cols;
	private final int[][] content;
	
	public Matrix(int rows, int cols)
	{
		this.rows = rows; this.cols = cols;
		this.content = new int[rows][];
		// Initialize the matrix
		for (int i = 0; i < rows; i++) this.content[i] = new int[cols];
	}
	
	public static Matrix createIdentity(int n)
	{
		Matrix m = new Matrix(n, n);
		for (int i = 0; i < n; i++) m.set(i, i, 1);
		return m;
	}
	
	public int getRows() { return rows; }
	public int getCols() { return cols; }
	public int get(int i, int j) { return content[i][j]; }
	public void set(int i, int j, int value) { content[i][j] = value; }
	
	@Override public int describeContents()  { return 0; }

	@Override
	public void writeToParcel(Parcel dest, int flags) 
	{
		dest.writeInt(rows);
		dest.writeInt(cols);
		// Write the matrix row by row
		for (int i = 0; i < rows; i++)
			for (int j = 0; j < cols; j++)
				dest.writeInt(content[i][j]);
	}
	
	public static final Creator<Matrix> CREATOR =
		new Creator<Matrix>()
		{
			@Override
			public Matrix createFromParcel(Parcel source) 
			{
				int rows = source.readInt(), cols = source.readInt();
				Matrix m = new Matrix(rows, cols);
				for (int i = 0; i < rows; i++)
					for (int j = 0; j < cols; j++)
						m.set(i, j, source.readInt());
				return m;
			}

			@Override
			public Matrix[] newArray(int size) 
			{
				return new Matrix[size];
			}
		};

	@Override
	public String toString()
	{
		return Arrays.deepToString(content);
	}
}

Implantation du service

On implante la souche de IMatrixMultiplier. La souche a été auto-générée depuis l'interface AIDL.

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.matriservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import fr.upem.matrixlibrary.IMatrixMultiplier;
import fr.upem.matrixlibrary.Matrix;

/** A service providing multiplications on matrices */
public class MatrixMultiplierService extends Service 
{
	private final IBinder multiplier = new IMatrixMultiplier.Stub()
	{
		@Override
		public Matrix pow(Matrix m, int power) throws RemoteException
		{
			if (power == 0) return Matrix.createIdentity(m.getRows());
			if (power % 2 == 0)
			{
				Matrix m2 = pow(m, power / 2);
				return multiply(m2, m2);
			} else
			{
				// power % 2 == 1
				return multiply(m, pow(m, power-1));
			}
		}
		
		@Override
		public Matrix multiply(Matrix m1, Matrix m2) throws RemoteException 
		{
			if (m1.getRows() != m2.getCols())
				throw new IndexOutOfBoundsException("Dimension of matrices not compatible");
			Matrix r = new Matrix(m1.getRows(), m2.getCols());
			for (int i = 0; i < r.getRows(); i++)
				for (int j = 0; j < r.getCols(); j++)
				{
					int v = 0;
					for (int k = 0; k < m1.getCols(); k++)
						v += m1.get(i, k) * m2.get(k, j);
					r.set(i, j, v);
				}
			return r;
		}
	};
		
	@Override
	public IBinder onBind(Intent arg0) { return multiplier; }
}

Connexion au service

ServiceConnection conn = new ServiceConnection() 
{
	
	@Override public void onServiceDisconnected(ComponentName name) 
	{
		Toast.makeText(MatrixMultiplier.this, "Disconnected", Toast.LENGTH_LONG).show();
	}
	
	@Override public void onServiceConnected(ComponentName name, IBinder service) 
	{
		Toast.makeText(MyActivity.this, "Connected", Toast.LENGTH_LONG).show();
		IMatrixMultiplier matmul = IMatrixMultiplier.Stub.asInterface(service) ;
		Matrix m = new Matrix(2,2);
		m.set(0,0, 1); m.set(0,1, 2);
		m.set(1,0, 3); m.set(1,1, 4);
		Matrix r = null;
		try {
			r = matmul.multiply(m, m);
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		if (r != null)
			t.setText(r.toString());
	}
};
boolean connected = 
	bindService(new Intent().setClassName("fr.upemlv.matriservice", 
		"fr.upemlv.matriservice.MatrixMultiplierService"), 
		conn, Context.BIND_AUTO_CREATE);

Service local

Inutile de mettre en œuvre une interface AIDL si le service n'est utilisé que localement dans l'application.

public class LocalService extends Service
{
	public class LocalBinder extends Binder
	{
		LocalService getService() 
		{ 
			return LocalService.this ; 
		}
	}

	private final IBinder binder = new LocalBinder() ;

	@Override public IBinder onBind(Intent intent) 
	{
		return binder;
	}

	...
}

On peut ensuite récupérer le LocalBinder dès la connexion au service et récupérer avec la méthode getService() l'instance du LocalService (et ainsi potentiellement manipuler tous ses champs et méthodes publiques).