Android WebView rend en blanc/blanc, vue n'est pas mise à jour sur le css des changements ou des modifications HTML, les animations sont saccadées
Lorsque j'ai jamais faire une classe css changement, les changements ne sont pas toujours visibles. Ce qui semble arriver quand j'ai un événement tactile qui ajoute quelque chose comme un bas nom de la classe à un bouton. Le bouton n'est pas à jour, et ni ne fait rien d'autre sur la page. C'est très inconstante dans quand il fonctionne. J'ai aussi remarqué que parfois mes éléments apparaissent en blanc, sans contenu ou quoi que ce soit. C'est très frustrant!
Vous devez vous connecter pour publier un commentaire.
J'ai mis en place de kyle solution et il a résolu le problème. Howewer j'ai remarqué une énorme consommation de la batterie sur android 4.0.4 lorsque l'application est ouverte. Aussi, après le changement, j'ai eu les utilisateurs se plaignent que l'swiftKey clavier ne fonctionnait pas avec mon app plus.
Chaque changement dans mon application sont déclenchés par une action de l'utilisateur alors je suis venu avec une version modifiée de déclencher invalidate() après un touchEvent:
N'a jamais fait de programmation avec Java donc il y aura peut être une meilleure solution pour ce faire.
Remarque:
Il y a une meilleure solution que de Android 4.4+. C'est un drop-in
WebView
de remplacement appelé tableau de Concordance de l'. Il utilise la plus récente de Chrome-kit et c'est fantastique. Vous pouvez lire à ce sujet ici: crosswalk-project.orgAussi, il semble que depuis Android 4.4, le
invalidate()
solution n'est plus nécessaire et vous pouvez vous en sortir avec l'aide de certains de l'autre plus sûr de la réponse. Je ne utiliser ceinvalidate()
approche comme un ultime effort.Je vais répondre à ma propre question, j'espère aider les gens avec les mêmes problèmes que moi.
J'ai essayé plusieurs méthodes pour améliorer les choses, même les toutes notoire -
webkit-transform: translate3d(0,0,0);
Même cela ne fonctionne pas trop bien.Permettez-moi de partager avec vous ce qui a fait le travail.
Tout d'abord, utiliser la plus récente de l'API. Je suis l'aide de l'API 15. Dans votre
AndroidManifest.xml
, assurez-vous d'activer l'accélération matérielle. Si votre version de l'API ne prend pas en charge ce, puis passer à la partie suivante.Si votre version ne prend en charge, vous pouvez l'activer en modifiant votre manifeste:
Aussi, assurez-vous que votre manifeste est le minimum API pris en charge pour celui que vous êtes en utilisant. Depuis que je suis en utilisant l'API de 15, c'est ce que mon manifeste a:
(Mise à jour: vous devez maintenant modifier les valeurs dans votre
build.gradle
)Maintenant, dans votre premier fichier CSS pour ce qui va être présenté dans une WebView, ajouter quelque chose comme ceci:
Ajouter sur le corps div peu avec tout autre type d'élément que vous avez; vous pouvez probablement exclure les images,
ul
,li
, etc. La raison pour appliquer le style CSS pour tout ce qui est juste par essai et erreur, et j'ai trouvé que la brute de l'appliquer à tout ce qui semble fonctionner le mieux. Avec une plus grande arborescence DOM, vous devrez peut-être plus spécifique. Je ne suis pas sûr de ce que la norme serait, cependant.Lorsque vous instanciez votre
WebView
, il y a certains paramètres que vous devrez définir:Seconde à la dernière, mais crucial peu: j'ai été en lisant le code source de la
WebView
la classe et a trouvé ce petit commentaire à propos de la force de la redessiner. Il y a unstatic final boolean
, que lorsque la valeurtrue
force la vue pour toujours redessiner. Je ne suis pas énorme sur la syntaxe Java, mais je ne pense pas que vous pouvez modifier directement un static final attribut d'une classe. Donc, ce que j'ai fais, j'ai étendu la classe comme ceci:Gardez à l'esprit, je suis en utilisant Cordova/PhoneGap, j'ai donc dû étendre à partir de la
CordovaWebView
. Si vous voyez dans la méthode onDraw, il y a un appel àinvalidate
. Ce sera la cause de la vue de redessiner sans cesse. Je recommande fortement l'ajout d'une logique pour seulement redessiner lorsque vous en avez besoin, cependant.Il y a une dernière étape, si vous êtes à l'aide de Cordoue. Vous avez à dire à PhoneGap pour utiliser votre nouveau
WebView
classe au lieu de leur propreWebView
classe. Dans votreMainActivity
catégorie, ajouter ceci:Que c'est! Essayez et d'exécuter votre application et de voir si tout est beaucoup plus lisse. Avant de faire tous ces changements, les pages apparaissent en blanc, pas de CSS changements seront appliqués jusqu'à ce que après avoir appuyé sur l'écran, les animations étaient super agitée ou n'est même pas perceptible. Je dois mentionner que les animations sont toujours instable, mais beaucoup moins agitée qu'auparavant.
Si quelqu'un a quelque chose à ajouter à cela, il suffit de commenter sous. Je suis toujours ouvert pour des optimisations; et j'en suis pleinement conscient, il peut y avoir de meilleures façons de faire ce que je viens de recommandé.
Si ma solution ci-dessus ne fonctionne pas pour vous, pourriez-vous décrire votre situation spécifique et quels sont les résultats que vous voyez avec des Androïdes
WebView
?Enfin, je l'ai activé cette réponse comme un "wiki de la communauté", donc n'importe qui et tout le monde, n'hésitez pas à faire des ajustements.
Merci!
Edit:
Avec la plupart des derniers PhoneGap, vous aurez besoin d'avoir votre méthode init() de ressembler à ceci:
View
dans sononDraw()
est une chose que vous devez PAS ne sous Android! Comme @VicVu dit, il se retrouve dans une boucle infinie redessiner la vue, encore et encore. Il va consommer d'énormes quantités de mémoire et de la force de la GPU de travailler en permanence. C'est à peu près le pire des cas qui peuvent arriver à une application, de sorte que jamais de le faire. Je suis assez étonné de cette réponse a beaucoup de upvotes. @Kyle, vous devez certainement supprimer "invalidate
-trick" de votre réponse!invalidate()
-hack et il suffit de garder les autres approches. Ce serait la solution la plus évidente que leinvalidate()
-hack est clairement un anti-modèle, une chose que vous ne devriez jamais faire ou de le recommander à d'autres développeurs. Il suffit de garder le matériel acelleration truc et le seul à l'aide de CSS transformations 3D. Ne m'obtenez pas le mal, mais queinvalidate()
-hacky-bit n'est pas le genre de solution que nous voulons avoir sur StackOverflow.re: le redessiner problème, vous pouvez forcer un redessiner par la lecture d'une propriété de l'élément
dire si vous faites cela:
si vous le faites par la suite:
elle force un redessiner.
De cette façon, vous pouvez être sélectif au lieu de redessiner l'ensemble de la page tout le temps, ce qui est coûteux
Pour moi, cette question a été produit seulement sur les appareils Samsung. J'ai été en mesure de le réparer par la désactivation de l'Accélération Matérielle pour les WebViews:
Espère que cela aide.
Comme l'a souligné ci-dessus et ailleurs primordial
View.onDraw()
et de l'appel deView.invalidate
en sera que plus malheureux de la batterie /les performances de l'application va baisser. Vous pouvez également faire un manuelinvalidate
appeler jamais x ms commeJ'ai essayé de mettre un invalider appel dans
WebViewClient.onPageLoaded()
mais cela ne semble pas fonctionner. Même si ma solution pourrait être mieux c'est simple et cela fonctionne pour moi (je suis en train de montrer une connexion de twitter)onPageFinished
de rappel. La méthode commentaire fait référence à ne pas être en mesure d'appelermWebView.invalidate();
dansonPageFinished
Voir aussi ma réponse à WebView ne parvient pas à rendre jusqu'touché Android 4.2.2 , L'idée est d'exporter @Olivier de la fonction JavaScript de sorte que vous pouvez déclencher invalide JS sensible pièces ... Mon dieu, encore un autre plus hack !! 🙂
J'ai eu ce problème parce que onPageStared et onPageFinished j'ai d'afficher et de masquer une animation de chargement.
Depuis a été l'injection de JS faire mes menus et des trucs sur le site web original et remarqué que l'injection de JS sur onPageFinished de la force de la webview pour dessiner le contenu. Voici un exemple de ce que vous pouvez ajouter à la fin de onPageFinished
Vider le cache de webView dans oncreate() et ça marche pour moi.