Tous les produits
Search
Centre de documentation

ApsaraVideo VOD:Stratégie de cycle de vie du lecteur

Dernière mise à jour :Sep 11, 2026

Ce document décrit le contexte de conception, les types de stratégies et l'utilisation de la stratégie de cycle de vie du lecteur AliPlayerKit.

Contexte

La stratégie de cycle de vie du lecteur est un modèle de conception abstrait à partir du pool de lecteurs multi-instances initialement mis en œuvre pour les applications de courts métrages d'Alibaba Cloud. Cette conception permet un défilement vidéo rapide en utilisant un pool d'instances de lecteur partagé globalement pour offrir les avantages suivants :

  1. Réutilisation des instances : réduit la surcharge liée à la création de nouvelles instances.

  2. Configuration dynamique : contrôle flexible du nombre d'instances.

  3. Optimisation des threads : offre un contrôle fin des ressources thread.

Cette approche garantit un chargement rapide de la première image, une transition fluide et une empreinte mémoire maîtrisée, ce qui la rend adaptable à une large gamme de scénarios métier.

Concepts clés

Qu'est-ce qu'une stratégie de cycle de vie du lecteur ?

Une stratégie de cycle de vie du lecteur est une architecture permettant de gérer le cycle de vie des instances de lecteur. Elle définit les opérations fondamentales telles que l'acquisition, le recyclage et la suppression, découplant ainsi la gestion des ressources du lecteur de la logique métier.

Les différents scénarios métier ont des exigences distinctes en matière de gestion des instances de lecteur :

Cas d'utilisation

Exigences

Stratégie recommandée

Lecture vidéo standard

Simple et directe, aucune réutilisation nécessaire.

default strategy

Liste de vidéos courtes

Changements fréquents, nécessite un démarrage rapide.

reuse pool strategy

Préchargement vidéo

L'instance est liée à un ID et prend en charge le préchargement.

ID-scoped strategy

Scénarios sensibles à la mémoire

Une seule instance globale pour une empreinte mémoire minimale.

singleton strategy

Avantages du modèle de stratégie

Le modèle de stratégie offre les avantages principaux suivants pour la gestion du cycle de vie du lecteur :

  • Découplage : sépare la logique métier des détails de création et de destruction des instances de lecteur.

  • Flexibilité : permet de changer de stratégie au moment de l'exécution sans modifier la logique métier.

  • Extensibilité : vous pouvez implémenter des stratégies personnalisées pour répondre à des besoins métier spécifiques.

  • Observabilité : des événements de cycle de vie unifiés facilitent la surveillance et le débogage.

Fonctionnalités

Problèmes résolus

  1. Gestion décentralisée : absence de mécanisme unifié pour contrôler les instances de lecteur.

  2. Surcharge des performances : la création et la destruction fréquentes des instances de lecteur gaspillent des ressources.

  3. Difficultés de réutilisation : les instances de lecteur ne peuvent pas être réutilisées dans différents scénarios.

  4. Mémoire non contrôlée : manque de contrôle efficace sur l'empreinte mémoire.

Valeur principale

Utilisation

Description

Avantage

default strategy

Crée une nouvelle instance pour chaque utilisation et la détruit ensuite.

Simple et directe, sans état résiduel.

reuse pool strategy

Maintient un pool d'objets pour réutiliser les instances inactives.

Réduit la surcharge de création et améliore la vitesse de démarrage.

ID-scoped strategy

Maintient une instance distincte pour chaque ID.

Prend en charge le préchargement et la réutilisation liée à l'ID.

singleton strategy

Une seule instance globale.

Empreinte mémoire minimale.

Avantages architecturaux :

  • Découplage des stratégies : la gestion des ressources du lecteur est séparée de la logique métier pour une responsabilité claire.

  • Commutation au moment de l'exécution : changez de stratégie sans redémarrer l'application.

  • Sécurité des threads : toutes les implémentations de stratégie prennent en charge un accès sécurisé depuis plusieurs threads.

  • Piloté par les événements : publie des événements de cycle de vie via un bus d'événements pour faciliter la surveillance.

Capacités principales

Capacité

Description

Acquisition d'instance

acquire() Acquiert une instance de lecteur. La stratégie détermine s'il faut créer une nouvelle instance ou en réutiliser une existante.

Recyclage d'instance

recycle() Recycle une instance de lecteur. La stratégie détermine s'il faut la détruire ou la conserver.

Nettoyage des ressources

clear() Nettoie toutes les ressources, garantissant une libération sécurisée.

Préchargement

preload() Crée des instances à l'avance pour réduire le temps jusqu'à la première image.

Contrôle de la capacité du pool

setMaxPoolSize() Ajuste dynamiquement la capacité du pool.

Composants intégrés

Types de stratégies

AliPlayerKit fournit quatre stratégies de cycle de vie du lecteur intégrées :

Stratégie

Description

Cas d'utilisation

Empreinte mémoire

DefaultLifecycleStrategy

La stratégie par défaut. Crée une nouvelle instance pour chaque utilisation et la détruit immédiatement après.

Scénarios de lecture standard, simple et directe.

Faible

ReusePoolLifecycleStrategy

La stratégie de pool de réutilisation. Maintient un pool inactif et utilise une politique LIFO (Last-In, First-Out) pour la réutilisation.

Listes de vidéos courtes et flux d'informations.

Moyenne

IdScopedPoolLifecycleStrategy

La stratégie étendue par ID. Maintient une instance distincte pour chaque ID et utilise une politique LRU (Least Recently Used) pour l'éviction.

Préchargement vidéo, commutation multi-vidéo.

Moyenne

SingletonLifecycleStrategy

La stratégie singleton. Une seule instance globale.

Scénarios sensibles à la mémoire, lecture vidéo unique.

La plus faible

Détails des stratégies

DefaultLifecycleStrategy (stratégie par défaut)

Il s'agit de la stratégie la plus simple. Chaque appel à acquire() crée une nouvelle instance, et chaque appel à recycle() la détruit immédiatement.

Points clés :

  • Sans état, fournissant une nouvelle instance à chaque fois.

  • Aucune réutilisation, adaptée aux scénarios simples.

  • Empreinte mémoire la plus faible (les ressources sont libérées immédiatement après utilisation).

ReusePoolLifecycleStrategy (stratégie de pool de réutilisation)

Basée sur le modèle de pool d'objets, cette stratégie maintient un pool inactif et une liste active. Elle utilise une politique LIFO (Last-In, First-Out) pour réutiliser les instances.

Points clés :

  • Politique LIFO pour le pool inactif, où l'instance utilisée le plus récemment est réutilisée en premier.

  • Prend en charge le préchargement pour créer des instances à l'avance.

  • Capacité du pool configurable. Les instances sont détruites si la capacité est dépassée.

  • Idéale pour les listes de vidéos courtes et les scénarios de flux d'informations.

Remarque

Chaque instance de lecteur consomme environ 35 à 40 Mo de mémoire. La capacité par défaut du pool est de 3, que vous pouvez ajuster en fonction des performances de l'appareil.

IdScopedPoolLifecycleStrategy (stratégie étendue par ID)

Maintient une instance de lecteur distincte pour chaque uniqueId, renvoyant toujours la même instance pour un ID donné. Elle utilise un mécanisme LRU (Least Recently Used) pour contrôler le nombre d'instances.

Points clés :

  • Liée à l'ID, réutilise toujours la même instance pour le même ID.

  • Le mécanisme d'éviction LRU nettoie automatiquement les instances utilisées le moins récemment.

  • Prend en charge le préchargement pour créer des instances non liées à l'avance.

  • Idéale pour le préchargement vidéo et les scénarios de commutation multi-vidéo.

SingletonLifecycleStrategy (stratégie singleton)

Maintient une seule instance de lecteur globale. Elle renvoie toujours la même instance, quel que soit le uniqueId.

Points clés :

  • Unique globalement, tous les appelants partagent la même instance.

  • Empreinte mémoire la plus faible.

  • Non adaptée à la lecture simultanée de plusieurs vidéos.

Événements de cycle de vie

La stratégie publie des événements de cycle de vie auxquels vous pouvez vous abonner sur le bus d'événements :

Événement

Description

Déclenchement

PlayerCreated

Un lecteur est créé.

Lorsqu'une nouvelle instance est créée.

PlayerDestroyed

Un lecteur est détruit.

Lorsqu'une instance est détruite.

PlayerReused

Un lecteur est réutilisé.

Lorsqu'une instance est récupérée du pool pour réutilisation.

PlayerHit

Une instance de lecteur est trouvée.

Lorsqu'une instance existante est trouvée pour un ID donné.

PlayerEvicted

Un lecteur est évincé.

Lorsqu'une instance est évincée par la politique LRU ou parce que le pool est plein.

Utilisation de base

Utiliser la stratégie par défaut

C'est la manière la plus simple d'utiliser le lecteur, sans configuration supplémentaire nécessaire :

// Create a controller (automatically uses DefaultLifecycleStrategy)
AliPlayerController controller = new AliPlayerController(context);

// Bind the player
AliPlayerModel model = new AliPlayerModel.Builder()
        .videoSource(videoSource)
        .build();
controller.configure(model);
playerView.attach(controller);      

Utiliser la stratégie de pool de réutilisation

Cette stratégie est idéale pour les listes de vidéos courtes et les scénarios de flux d'informations :

// Get the singleton instance of the reuse pool strategy
ReusePoolLifecycleStrategy strategy = ReusePoolLifecycleStrategy.getInstance();

// Set the pool capacity (optional, defaults to 3)
strategy.setMaxPoolSize(3);

// Inject the strategy when creating the controller
AliPlayerController controller = new AliPlayerController(context, strategy);

// Clean up resources when finished
strategy.clear(); 

Utiliser la stratégie étendue par ID

Cette stratégie est idéale pour les scénarios nécessitant un préchargement et une commutation entre plusieurs vidéos :

// Get the singleton instance of the ID-scoped strategy
IdScopedPoolLifecycleStrategy strategy = IdScopedPoolLifecycleStrategy.getInstance();

// Set the pool capacity
strategy.setMaxPoolSize(3);

// Preload player instances (optional)
strategy.preload(context, 2);

// Inject the strategy when creating the controller
AliPlayerController controller = new AliPlayerController(context, strategy);

// Clean up resources when finished
strategy.clear(); 

Utiliser la stratégie singleton

Cette stratégie est idéale pour les scénarios sensibles à la mémoire :

// Get the singleton strategy instance
SingletonLifecycleStrategy strategy = SingletonLifecycleStrategy.getInstance();

// Preload the instance (optional, only creates one instance)
strategy.preload(context, 1);

// Inject the strategy when creating the controller
AliPlayerController controller = new AliPlayerController(context, strategy);

Utilisation avancée

Écoute des événements de cycle de vie

Écoutez les événements de cycle de vie internes d'une stratégie via le bus d'événements pour le débogage et la surveillance :

PlayerEventBus eventBus = PlayerEventBus.getInstance();

// Listen for player creation
eventBus.subscribe(PlayerLifecycleEvents.PlayerCreated.class, event -> {
    Log.d("Player", "Created: " + event.playerId);
});

// Listen for player reuse
eventBus.subscribe(PlayerLifecycleEvents.PlayerReused.class, event -> {
    Log.d("Player", "Reused: " + event.playerId);
});

// Listen for player eviction
eventBus.subscribe(PlayerLifecycleEvents.PlayerEvicted.class, event -> {
    Log.d("Player", "Evicted: " + event.playerId);
});

// Listen for player destruction
eventBus.subscribe(PlayerLifecycleEvents.PlayerDestroyed.class, event -> {
    Log.d("Player", "Destroyed: " + event.playerId);
});

// Unsubscribe when no longer needed
eventBus.unsubscribe(PlayerLifecycleEvents.PlayerCreated.class, listener);

Commutation dynamique des stratégies

Vous pouvez commuter les stratégies au moment de l'exécution en fonction des besoins métier :

private IPlayerLifecycleStrategy mCurrentStrategy;

private void switchToReusePool() {
    // 1. Clean up old resources
    if (mCurrentStrategy != null) {
        mCurrentStrategy.clear();
    }

    // 2. Switch to the reuse pool strategy
    mCurrentStrategy = ReusePoolLifecycleStrategy.getInstance();
    mCurrentStrategy.setMaxPoolSize(3);

    // 3. Preload
    mCurrentStrategy.preload(this, 2);
}

private void switchToSingleton() {
    // 1. Clean up old resources
    if (mCurrentStrategy != null) {
        mCurrentStrategy.clear();
    }

    // 2. Switch to the singleton strategy
    mCurrentStrategy = SingletonLifecycleStrategy.getInstance();
}

Préchargement des instances de lecteur

Le préchargement crée des instances de lecteur à l'avance pour réduire le temps jusqu'à la première image :

// Reuse pool strategy: Preloaded instances are placed in the idle pool
ReusePoolLifecycleStrategy strategy = ReusePoolLifecycleStrategy.getInstance();
strategy.preload(context, 2);  // Pre-create 2 instances// ID-scoped strategy: Preloads unbound instances
IdScopedPoolLifecycleStrategy strategy = IdScopedPoolLifecycleStrategy.getInstance();
strategy.preload(context, 2);  // Pre-create 2 unbound instances// Singleton strategy: Preloads the global instance
SingletonLifecycleStrategy strategy = SingletonLifecycleStrategy.getInstance();
strategy.preload(context, 1);  // Creates the global instance (the count parameter is ignored)

Implémentation d'une stratégie personnalisée

Implémentez une stratégie personnalisée en étendant BaseLifecycleStrategy :

public class MyCustomStrategy extends BaseLifecycleStrategy {

    private final Map<String, IMediaPlayer> playerMap = new HashMap<>();

    @NonNull@Overridepublic IMediaPlayer acquire(@NonNull Context context, @NonNull String uniqueId) {
        // Custom acquisition logic
        IMediaPlayer player = playerMap.get(uniqueId);
        if (player != null) {
            // Hit an existing instance
            PlayerEventBus.getInstance().post(
                new PlayerLifecycleEvents.PlayerHit(player.getPlayerId()));
            return player;
        }

        // Create a new instance
        player = createPlayer(context);
        playerMap.put(uniqueId, player);
        return player;
    }

    @Overridepublic void recycle(@Nullable IMediaPlayer player, @NonNull String uniqueId, boolean force) {
        if (player == null) return;

        if (force) {
            // Force destruction
            playerMap.remove(uniqueId);
            destroyPlayer(player);
        } else {
            // Only stop the player, keep the instance
            player.stop();
        }
    }

    @Overridepublic void clear() {
        // Clean up all instances
        for (IMediaPlayer player : playerMap.values()) {
            destroyPlayer(player);
        }
        playerMap.clear();
    }
}

Bonnes pratiques

Sélection de la stratégie

Cas d'utilisation

Stratégie recommandée

Description

Lecture vidéo standard

default strategy

Simple et directe, sans surcharge supplémentaire.

Liste de vidéos courtes (style TikTok)

reuse pool strategy

Réutilise les instances pour une commutation rapide.

Préchargement vidéo

ID-scoped strategy

Lie les instances aux IDs et prend en charge le préchargement.

Appareils bas de gamme

singleton strategy

Empreinte mémoire minimale.

Vidéos éducatives (commutation multi-vidéo)

ID-scoped strategy

Précharge la vidéo suivante.

Optimisation de la mémoire

Chaque instance de lecteur consomme environ 35 à 40 Mo de mémoire (selon les résultats de profilage mémoire du pool de lecteurs multi-instances d'Alibaba Cloud pour les courts métrages). Nous vous recommandons d'ajuster la capacité du pool en fonction des performances de l'appareil :

Type d'appareil

Configuration recommandée

Capacité du pool

Appareil haut de gamme

ReusePool ou IdScopedPool

3

Appareil milieu de gamme

ReusePool ou IdScopedPool

2

Appareil bas de gamme

Singleton

1 (par défaut)

Scénarios sensibles à la mémoire

Singleton

1

// Dynamically adjust based on device memory
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
boolean isLowMemory = am.isLowRamDevice();

if (isLowMemory) {
    // Use the singleton strategy on low-memory devices
    strategy = SingletonLifecycleStrategy.getInstance();
} else {
    // Use the reuse pool strategy on standard devices
    strategy = ReusePoolLifecycleStrategy.getInstance();
    strategy.setMaxPoolSize(isHighEndDevice ? 3 : 2);
}

Précautions

Élément

Description

Nettoyage rapide

Appelez clear() ou recycle(force=true) pour libérer les ressources lorsqu'une page est détruite.

Singletons de stratégie

Les classes ReusePoolLifecycleStrategy, IdScopedPoolLifecycleStrategy et SingletonLifecycleStrategy sont implémentées comme des singletons avec un état partagé globalement.

Sécurité des threads

Toutes les implémentations de stratégie sont thread-safe et peuvent être utilisées dans des environnements multi-threads.

Désabonnement aux événements

Pour éviter une fuite de mémoire, désabonnez-vous toujours des événements de cycle de vie au moment approprié.

Ordre d'initialisation

Les stratégies sont initialisées automatiquement. Vous n'avez pas besoin d'appeler init() manuellement.

Exemple

Un exemple complet est fourni dans le projet à l'emplacement playerkit-examples/example-lifecycle-strategy.

Fonctionnalités de l'exemple

Fonctionnalité

Description

Commutation de stratégie

Commutez dynamiquement entre les quatre stratégies intégrées.

Affichage de l'état

Affiche l'état en temps réel de la stratégie (créé/réutilisé/trouvé/évincé).

Écoute des événements

Écoute et affiche les événements de cycle de vie.

Lecture multi-vidéo

Démontre l'effet de la commutation entre plusieurs vidéos avec différentes stratégies.

Exécuter l'exemple

Dans l'application de démonstration, sélectionnez l'exemple Lifecycle Strategy pour le voir en action.

API

Interfaces principales

Interface/classe

Description

IPlayerLifecycleStrategy

L'interface de stratégie de cycle de vie du lecteur, qui définit les opérations principales.

BaseLifecycleStrategy

La classe de base des stratégies, qui encapsule la logique commune.

IPlayerFactory

L'interface de fabrique de lecteur, responsable de la création et de la destruction des instances.

Méthodes IPlayerLifecycleStrategy

Méthode

Description

init(IPlayerFactory)

Initialise la stratégie et injecte la fabrique de lecteur.

acquire(Context, String)

Acquiert une instance de lecteur.

recycle(IMediaPlayer, String, boolean)

Recycle une instance de lecteur.

clear()

Nettoie toutes les ressources.

preload(Context, int)

Précharge des instances de lecteur.

Méthodes BaseLifecycleStrategy

Méthode

Description

setMaxPoolSize(int)

Définit la capacité maximale du pool (effectif uniquement pour les stratégies basées sur un pool).

createPlayer(Context)

Crée une instance de lecteur (appelée par les sous-classes).

destroyPlayer(IMediaPlayer)

Détruit une instance de lecteur (appelée par les sous-classes).

Fonctionnement

Sécurité des threads

Stratégie

Sécurité des threads

DefaultLifecycleStrategy

Sans état et thread-safe.

ReusePoolLifecycleStrategy

Blocs synchronized.

IdScopedPoolLifecycleStrategy

Blocs synchronized.

SingletonLifecycleStrategy

AtomicReference + verrouillage à double vérification.

Comparaison des stratégies de mise en pool

Fonctionnalité

ReusePool

IdScopedPool

Mécanisme de réutilisation

LIFO (Last-In, First-Out)

Liaison ID + LRU

Prise en charge du préchargement

Oui (place les instances dans le pool inactif)

Oui (place les instances dans une file d'attente non liée)

Politique d'éviction

Évince lorsque le pool est plein

Éviction LRU automatique

Cas d'utilisation

Liste de vidéos courtes

Préchargement multi-vidéo

Logique architecturale sous-jacente :

  • Pourquoi la stratégie de pool de réutilisation utilise-t-elle LIFO (Last-In, First-Out) ?

    Dans les scénarios de défilement vertical fréquent dans un flux, l'instance de lecteur qui vient d'être ajoutée au pool inactif est la plus « chaude » en termes de contexte de décodeur sous-jacent et de ressources matérielles (son cache n'a pas encore été paginé par le système). La réutiliser en premier réduit considérablement le temps nécessaire aux réinitialisations de contexte de bas niveau, améliorant ainsi la vitesse de démarrage selon le principe de localité spatiale.

  • Pourquoi la stratégie étendue par ID utilise-t-elle LRU (Least Recently Used) ?

    La mise en pool multi-instances suit le principe de localité temporelle : lorsqu'un utilisateur fait défiler un flux, la probabilité de rejouer une vidéo beaucoup plus ancienne diminue. La politique d'éviction LRU s'aligne sur ce schéma de décroissance de l'historique de navigation de l'utilisateur, permettant un contrôle efficace de l'empreinte mémoire de pointe de l'application tout en maintenant une liaison stricte aux IDs.

FAQ

Choisir la bonne stratégie

Choisissez en fonction de votre scénario métier :

  • Lecture simple : utilisez la stratégie par défaut pour une complexité nulle.

  • Vidéos courtes/flux d'informations : utilisez la stratégie de pool de réutilisation pour une commutation rapide.

  • Préchargement vidéo : utilisez la stratégie étendue par ID pour la liaison ID.

  • Scénarios sensibles à la mémoire : utilisez la stratégie singleton pour l'empreinte la plus petite.

Définir la capacité du pool

Ajustez la capacité en fonction des performances de l'appareil et des besoins métier :

  • Chaque instance de lecteur consomme environ 35 à 40 Mo de mémoire.

  • La capacité par défaut du pool est de 3, ce qui consomme environ 100 à 120 Mo.

  • Pour les appareils bas de gamme, définissez la capacité à 2 ou utilisez la stratégie singleton.

Utiliser le préchargement

Utilisez le préchargement dans les scénarios où vous devez réduire le temps jusqu'à la première image :

  • Liste de vidéos courtes : préchargez 1 à 2 instances.

  • Page de détail vidéo : préchargez la vidéo recommandée suivante.

  • Évitez un préchargement excessif, car il augmente l'utilisation de la mémoire.

Pièges courants

Les situations suivantes sont les causes les plus courantes des problèmes signalés par les utilisateurs. Assurez-vous de les éviter :

Exemple 1 : Oubli d'appeler clear()

Code incorrect :

@Overrideprotected void onDestroy() {
    super.onDestroy();
    // Only detached the View, forgot to clean up instances held by the strategy
    mPlayerView.detach();
}

Code correct :

@Overrideprotected void onDestroy() {
    super.onDestroy();
    // Detach the View
    mPlayerView.detach();
    // Clean up strategy resources
    if (mStrategy != null) {
        mStrategy.clear();
    }
}

Cause : la stratégie (comme ReusePool) conserve des références aux instances de lecteur. Ne pas les nettoyer entraînera une fuite de mémoire.

Exemple 2 : Échec de la désinscription d'un écouteur d'événements

Code incorrect :

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Subscribed to an event but never unsubscribed
    PlayerEventBus.getInstance().subscribe(
        PlayerLifecycleEvents.PlayerCreated.class,
        event -> updateUI()
    );
}

Code correct :

private PlayerEventBus.EventListener<PlayerLifecycleEvents.PlayerCreated> mListener;

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mListener = event -> updateUI();
    PlayerEventBus.getInstance().subscribe(
        PlayerLifecycleEvents.PlayerCreated.class, mListener);
}

@Overrideprotected void onDestroy() {
    super.onDestroy();
    // Unsubscribe if (mListener != null) {
        PlayerEventBus.getInstance().unsubscribe(
            PlayerLifecycleEvents.PlayerCreated.class, mListener);
    }
}

Cause : le bus d'événements conserve une référence à l'Activity. Si l'écouteur n'est pas supprimé, l'Activity ne peut pas être libérée après sa destruction.

Exemple 3 : Utilisation d'une instance de lecteur après son recyclage

Code incorrect :

// Recycle the player
strategy.recycle(player, "video_1", false);

// Continue to use the player after recycling
player.start();  // May cause an exception

Code correct :

// Recycle the player
strategy.recycle(player, "video_1", false);
player = null;  // Clear the reference to prevent misuse. Re-acquire it when needed.
player = strategy.acquire(context, "video_1");

Cause : après le recyclage d'une instance de lecteur, celle-ci peut être arrêtée ou détruite. Son utilisation ultérieure provoquera une exception.

Débogage

  1. Vérifiez les journaux : filtrez Logcat en utilisant tag:AliPlayerKit.

  2. Écoutez les événements de cycle de vie : observez les événements de création, de réutilisation et d'éviction sur le bus d'événements.

  3. Vérifiez l'état du pool : consultez la taille actuelle du pool et le nombre d'instances actives via les journaux.

  4. Analysez la mémoire : utilisez Android Profiler pour vérifier le nombre d'instances de lecteur et leur empreinte mémoire.