2011-07-22 3 views
4

Je reçois actuellement un "IllegalStateException n'a pas pu init init fenêtre" après l'exécution de mon application pendant quelques minutes. Je démarre trois services différents lorsque mon application démarre, chaque sondage (toutes les 1 secondes) un service Web RESTful différent. Après avoir récupéré/analysé le résultat, chaque service a un ContentProvider dans lequel il insère les nouvelles données. Le ContentProvider utilise ensuite setNotificationUri pour indiquer à l'activité en cours que de nouvelles données sont disponibles (si elles sont abonnées pour obtenir des mises à jour de cet URI).Application Android CursorWindow erreur de mémoire

Première question, est-ce la bonne approche pour interroger un service web RESTful et obtenir le résultat pour les activités intéressées? Après avoir lu la réponse à this question, il semble que le ContentProvider est inutile parce que tout vit dans la même application.

Deuxième question, qu'est-ce qui pourrait causer l'exception IllegalStateException? Il s'avère qu'il n'y a pas assez de tas allouer le CursorWindow (l'allocation de tas cursorwindow a échoué). Je pensais que le problème était peut-être lorsque j'ai interrogé le ContentProvider (après avoir reçu la notification), il retournait trop de résultats dans le curseur. Les activités n'ont vraiment besoin que de la dernière mise à jour reçue, donc j'ai ajouté un DESC ORDER BY "ID" et j'ai limité le résultat à 1. Donc le ContentProvider ne devrait renvoyer qu'un résultat à chaque fois. Cela n'a vraiment pas fait de différence.

Toute aide à la première question peut également résoudre la deuxième question. J'ai lu quelques endroits pour ne pas faire des appels de service Web au sein d'une activité qui m'a conduit à utiliser une classe de service pour interroger les services Web. Juste pour info, ceci est une application interne qui n'aura que quelques clients.

Merci pour vos commentaires.

Edit: Voici le code nécessaire pour l'une des requêtes:

Cursor geoEllipseDatas = managedQuery(GeoEllipseDataProvider.GEO_ELLIPSE_CONTENT_URI, 
       projection, null, null, GeoEllipseDataProvider.ID + " DESC"); 
     boolean dataAvailable = geoEllipseDatas.moveToLast(); 

if (dataAvailable) { 
    // parse the data out of the cursor 
    String targetId = geoEllipseDatas.getString(1); 
    ... 
} 

Répondre

0
  1. Après avoir passé les deux approches (ContentProvider et accès DB directe), personnellement, je trouve que ContentProvider sont une source moins de bugs. Ils sont vraiment faciles d'accès/configuration simplement en utilisant le résolveur de contenu, ils vous obligent à penser réellement aux URI et vous obtiendrez tous les avantages avec eux (comme les filtres d'intention sur ces URI, ...). Assurez-vous que vous fermez correctement les curseurs, libérez la mémoire, ... Difficile à dire sans aucun code.


D'après ce que je compris du cas d'utilisation ManagedQuery, vous devriez l'appeler dans la méthode onCreate de votre activité. Si vous l'appelez ailleurs, je pense qu'il est prudent d'appeler le stopManagingCursor avant de faire un autre managedQuery (je ne sais pas si cette fonction le fait automatiquement pour vous, il faudrait regarder les sources).

En outre, le problème pourrait être dans votre fournisseur de contenu, qui déclenche une mise à jour sur ce curseur, qui déclencherait une autre requête, qui tireraient une mise à jour, ce serait ...

+0

Merci pour les commentaires. Je suis d'accord sur le numéro (1), j'étais confus quand je lisais que vous ne devriez utiliser ContentProvider pour le partage de données en dehors de votre application. J'ai ajouté du code pour number (2) à la question, j'ai utilisé un "managedQuery" donc je ne pensais pas que je devais fermer le curseur. Il semble que j'ai peut-être fait une supposition incorrecte? – Sean

+0

réponse modifiée ci-dessus –

Questions connexes