LockCanvas () wirklich langsam

Testen Sie mein Spiel auf einem langsameren Gerät (Orange San Francisco aka ZTE Blade) und ich habe eine schreckliche Bildrate bekommen.

Ich habe einige Debug-Code in die Ziehschleife und entdeckt die folgende Zeile übernimmt 100ms:

  • DialogFragment programmgesteuert abweisen
  • OutOfMemoryError: Bitmap-Größe überschreitet VM-Budget: - Android
  • Android Studio 2.0 - Plugin ist zu alt, bitte aktualisieren Sie auf eine neuere Version, oder setzen Sie ANDROID_DAILY_OVERRIDE Umgebungsvariable auf
  • Erhalten Sie Ansicht von Fragment von FragmentActivity
  • Retrofit - Mehrere Endpunkte mit demselben RestAdapter
  • Google Drive-Integration mit der aktuellen Aktivität
  • c = mSurfaceHolder.lockCanvas(); 

    Wer sonst gesehen hat dieses Verhalten? Ich habe vorübergehend die Oberflächenansicht ersetzt, indem ich die Ansicht und die Implementierung von onDraw () erweitere und ich bekam eine viel bessere Framerate.

    Obwohl im allgemeinen surfaceView ist viel schneller auf meinem HTC Desire. Ich bin verdächtig, dass dies ein Android 2.1 Problem sein kann. Ich erwäge, das Telefon zu verwurzeln und es auf 2.2 zu aktualisieren, wenn möglich, aber ich wollte ein Gerät, das auf 2.1 läuft, so dass es auf lange Sicht kontraproduktiv sein könnte.

    ** Update **

    Ich habe an diesem etwas mehr gearbeitet und habe einige rätselhafte Aspekte entdeckt.

    Ich verwurzelte das Telefon und installierte 2.2 und das Problem passiert immer noch. Wenn die App zum ersten Mal gestartet wird, arbeitet die lockCanvas wie erwartet (0-1 ms). Dann irgendwann bei meiner Initialisierung beginnt lockCanvas plötzlich ca. 100ms.

    Es lohnt sich, darauf hinzuweisen, dass ich meine Assets in einer Async-Aufgabe lade, so dass ich einen Ladebildschirm anzeigen kann.

    Trotz meiner besten Bemühungen, festzulegen, was das Programm tatsächlich tut, wenn die Langsamkeit auftritt, war ich nicht in der Lage, dies zu tun. In der Tat, wenn ich es im Debug-Modus und Single-Step, es funktioniert schnell!

    Jetzt habe ich entdeckt, dass, wenn ich eine Verzögerung in den Konstruktor meiner SurfaceView (von etwa 10 Sekunden) hinzufügen, die Langsamkeit nicht auftritt und alles funktioniert gut.

    Wenn du aber nach Hause kommst und dann zurückschreibst, kommt die Langsamkeit zurück.

    Ich bin so ziemlich am Ende meines Tetters auf diesem dummen unlogischen Problem! Ich habe einen Verstand, um es auf ein Gerät spezifisches Problem zu setzen.

    Ich glaube, es könnte etwas mit Gedächtnisgebrauch zu tun haben. Vielleicht wird etwas ausgetauscht und es beeinflusst den Video-RAM?

    Ich würde mich zumindest für Theorien interessieren.

  • LocalBroadcastManager vs Context.registerReceiver (), Context.sendBroadcast (Intent) und Context.unregisterReceiver () sind sie gleich?
  • Android: Was ist der Unterschied zwischen setFlags und addFlags für die Absicht
  • API-Schlüssel für GCM ist plötzlich ungültig? Unbefugter (401) Fehler
  • Android: Wie speichern url in string.xml Ressource Datei?
  • Android und Dependency Injection
  • Verwenden Sie verschiedene Ressourcen für verschiedene Anwendungs-Aromen mit Gradle
  • 4 Solutions collect form web for “LockCanvas () wirklich langsam”

    Über lockCanvas () von docs:

    Wenn Sie dies wiederholt anrufen, wenn die Oberfläche nicht bereit ist (vor Callback.surfaceCreated oder nach Callback.surfaceDestroyed), werden Ihre Anrufe zu einer langsamen Rate gedrosselt, um zu vermeiden, dass CPU verbraucht wird.

    Ist es möglich, dass Ihre Zugschleife zu früh für einige Geräte eingeleitet wird? Ich denke, das ist das Problem, da du geschrieben hast:

    Jetzt habe ich entdeckt, dass, wenn ich eine Verzögerung in den Konstruktor meiner SurfaceView (von etwa 10 Sekunden) hinzufügen, die Langsamkeit nicht auftritt und alles funktioniert gut.

    Also, vielleicht könnten wir holder.isCreating () verwenden, um den Zustand zu überprüfen? Diese Methode wird true zurückgeben, wenn Leinwand noch erstellt wird.

    Etwas wie während (holder.isCreating ()) {} can = holder.lockCanvas ();

    Aber ich bin jetzt ein bisschen verwirrt Wie ich weiß, wird colbeck genannt, wenn eine Oberflächenansicht erstellt wird. Wir sollten SurfaceHolder.Callback Schnittstelle implementieren. Und wenn die Oberfläche erstellt wird Callback-Methode public void surfaceCreated (SurfaceHolder Inhaber) {} wird aufgerufen. Von surfaceCreated Methode Ich beginne Gameloop Thread.

    Ich habe vor kurzem entdeckt, dass, wenn große Bitmaps verwendet werden, um auf die Leinwand zu ziehen und diese Bitmaps in der Aktivitätsklasse gespeichert sind – der Befehl "_surfaceHolder.lockCanvas ()" selbst dauert sehr lange (ca. 70ms je nach Gerät). Jedenfalls bewegen Sie diese Bitmaps-Speicherung in andere Klasse (in einer anderen Datei, sagen MY_DATA), und die Aktivität hat nur einen Hinweis auf diese neue Klasse – löst das Problem.

    Ich habe keine Erklärung für dieses Phänomen.

    Ich habe das gleiche mysteriöse Problem mit der Canvas , aber es löste es, indem ich die Canvas auf das SurfaceView . Aber jetzt habe ich ständig langsam lockCanvas() Anruf. Hier sind meine Beobachtungsergebnisse. Problem ist nur bei einigen Geräten vorhanden:

    • Galaxy Note 3 n900: hat Probleme
    • Galaxy Note 3 n9005: hat Probleme
    • Galaxy S4 i9505: hat Probleme
    • Galaxy Gio: keine Probleme
    • LG G2 D802: hat Probleme
    • Galaxy S2 i9100: keine Probleme

    Ich habe vorübergehend die Oberflächenansicht ersetzt, indem ich die Ansicht und die Implementierung von onDraw () erweitere und ich bekam eine viel bessere Framerate

    Ich habe auch bemerkt, dass Samsung Handys mit GLES20Canvas anstelle von regulären Canvas mit onDraw() Zeichnung, als Ergebnis, bessere Leistung.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.