2013-07-07 1 views
1

J'ai un SpiceRequest dont le travail consiste à pré-mettre en mémoire cache un ensemble de données, qui peuvent ensuite être chargées individuellement dans des SpiceRequests séparées. Par exemple, imaginons que mon application télécharge les temps de film pour un théâtre particulier via une SpiceRequest, j'ai besoin d'une SpiceRequest composite qui télécharge et prépresse tous les temps de film pour tous les cinémas d'une région.Robospice: Sauvegarde en cache à partir d'une SpiceRequest

Appelons cela AllMoviesSpiceRequest, c'est une sous-classe de SpringAndroidSpiceRequest. Sa méthode loadDataFromNetwork() effectue plusieurs appels à getRestTemplate(). GetForObject(). Il place toutes les données dans un objet conteneur et les renvoie.

Mon plan est lorsque onRequestSuccess est appelé pour appeler SpiceManager.putInCache pour chaque théâtre. Le problème est que l'ensemble de données pour tous les cinémas est grand, environ 16 Mo et qu'il obtient une erreur OutOfMemory due à JsonWriter.string() n'étant pas capable de sérialiser une chaîne aussi grande.

Est-il possible de mettre en cache chaque salle directement à partir de AllMoviesSpiceRequest en cours de téléchargement? Je ne suis pas sûr si son coffre-fort pour créer et appeler un SpiceManager d'un SpiceRequest. Ou y a-t-il une meilleure approche à adopter?

Voici quelques exemples de code pour vous donner l'idée:

public class AllMoviesSpiceRequest extends 
    SpringAndroidSpiceRequest<AllMovieTimes> { 

    public AllMovieTimes loadDataFromNetwork() throws Exception { 

     AllMovieTimes allMovieTimes = new AllMovieTimes(); 

     // Get all the theaters 
     Theaters theaters = getRestTemplate().getForObject(
      THEATER_JSON_URL + "/" + regionId, Theaters.class); 

     // Get all the movies 
     for(Theater t : theaters.all()) { 
      MovieTimes mt = getRestTemplate().getForObject(
       MOVIES_JSON_URL + "/" + t.getId(), MovieTimes.class); 

      allMovieTimes.add(mt); 
      // Can I call spiceManager.putInCacheHere??? 
     } 

     // OutOfMemoryError!!! 
     return allMovieTimes; 
    } 
} 

private class AllMoviesRequestListener implements 
    RequestListener<AllMovieTimes> { 

    public void onRequestSuccess(AllMovieTimes allMovieTimes) { 

     // Add all the movies to the cache 
     for(MovieTime mt : allMovieTimes) { 
      spiceManager.putInCache(mt.getCacheKey(), mt); 
     } 
    } 
} 

Merci à l'avance ...

Répondre

1

Si le résultat est trop important pour être traité par Jackson, qui pourrait être un problème de conception.

Avoir un json de 16 Mo n'est pas une bonne solution pour mobile. Cela laisserait longtemps vos utilisateurs avec un téléphone utilisable, et ce n'est pas ainsi qu'une application Android devrait fonctionner. Même si RS permet de télécharger des données en arrière-plan, vous devez vraiment vous préoccuper de la réactivité.

Dans RS toutes les données qui résultent d'une requête REST seront enregistrées directement et il n'est pas possible de les scinder plus tard. Au moins, cela est vrai avec la sérialisation Jackson/Gson. Json n'est pas une base de données et ne peut plus vous donner un accès sélectif aux données. Je pourrais répondre que vous devriez aller vers une sérialisation des données dans une base de données, en utilisant ORMLite, éventuellement avec le module RS ORMLite, qui pourrait vous permettre de stocker des choses dans des tables séparées et plus tard vous seriez capable de les récupérer sélectivement. Cependant, la vraie réponse ici est que vous devriez éviter de télécharger une telle quantité de données, ou peut-être utiliser quelque chose comme un format binaire (protobuf, kryo?) Et stocker des choses dans une base de données.

Mais la solution la plus simple et la plus courante consiste à télécharger une plus petite quantité de données.

Questions connexes