Android – Update Bitmap aus Timer Thread

Ich habe ein Android-Projekt aus einem einzigen Layout mit einem ImageView.

public class MainActivity extends AppCompatActivity { /* original and stretched sized bitmaps */ private Bitmap bitmapOriginal; private Bitmap bitmapStretched; /* the only view */ private ImageView iv; .... } 

Diese ImageView wird durch diese lauffähige Funktion aktualisiert

  • Wie kommuniziert man mit einem USB-Gerät?
  • Handler vs Thread
  • Genymotion Device erscheint nicht auf Device Chooser - Android Studio
  • Android Horizontale LinearLayout - Wrap Elemente
  • BitmapFactory OOM macht mich verrückt
  • Die Spracherkennung funktioniert nicht, wenn die Stimme aufgenommen wird
  •   runnable = new Runnable() { @Override public void run() { iv.setImageBitmap(bitmapStretched); } }; 

    Und das Runnable wird von einer temporären JNI-Funktion ausgeführt, die auf einem Hintergrund-Thread läuft, der es 60 mal pro Sekunde nennt.

     public void jniTemporizedCallback(int buf[]) { /* set data to original sized bitmap */ bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight); /* calculate the stretched one */ bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height, false); /* tell the main thread to update the image view */ runOnUiThread(runnable); } 

    Nachdem ein Frame gezeichnet ist, stürzt die App mit der folgenden Meldung ab.

     A/OpenGLRenderer: Task is already in the queue! 

    Ich denke, das ist, weil der Renderer nicht fertig ist, um den vorherigen Rahmen der ImageView vollständig zu machen und wird wütend.

    Wenn ich runOnUiThread(runnable); Das Problem verschwindet (offensichtlich)

    Wie kann das vermeiden? Wie kann ich meine Anwendung mit dem openGL Renderer synchronisieren?

    Ich habe auch versucht, ImageView zu erweitern und die Bitmap auf Leinwand in die onDraw-Funktion zu zeichnen, aber ich habe das gleiche Ergebnis

  • Import von PhoneGap-Projekt in Eclipse
  • Senden von Nachricht über WhatsApp By intent
  • So erstellen Sie das Android-Verzeichnis automatisch, wenn es noch nicht vorhanden ist
  • Auf der Suche nach einer plattformübergreifenden Methode für grundlegende 2D / 3D-Grafiken für iOS und Android
  • Gibt es keine Aufforderung im Android 4.x Spinner mehr?
  • Button button = findViewById (R.id.button) löst sich immer in Android Studio auf Null
  • 6 Solutions collect form web for “Android – Update Bitmap aus Timer Thread”

    Ich denke, du versuchst es, BitmapOriginal zu erstellen. Wenn also der Compiler nach 60 Sekunden wieder anruft, wird es immer dieselben Objekte und konnte die Aufgabe nicht identifizieren. Ich würde besser als unten vorschlagen.

      public void jniTemporizedCallback(int buf[]) { // Initialize bitmapOriginal = Bitmap.createBitmap(///) /* set data to original sized bitmap */ bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight); /* calculate the stretched one */ bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height,false); /* tell the main thread to update the image view */ runOnUiThread(runnable); } 

    Die richtige Möglichkeit, Ihre Zeichnungslogik mit der Bildrate des Geräts zu synchronisieren, besteht darin, eine SurfaceView anstelle eines ImageView zu verwenden. Anstatt mit dem eigenen Timer auf die Ansicht zu schieben, solltest du ein Rendering Thread erstellen, das versucht, Frames so schnell wie möglich zu rendern. Wenn du surfaceHolder.lockCanvas() , wird das Android-System automatisch blockiert, bis es Zeit ist, den Rahmen zu rendern. Wenn du die Leinwand mit unlockCanvasAndPost() entsperrst, unlockCanvasAndPost() das System den Puffer auf den Bildschirm.

    Weitere Informationen finden Sie unter https://developer.android.com/guide/topics/graphics/2d-graphics.html#on-surfaceview . Hoffe das hilft!

    Problem war völlig unabhängig von der Bitmap selbst ….

    Es war das Echtzeituhr-Signal, das mit Android RenderThread verwechselt wurde.

    Weitere Erläuterungen hier:

    Android und JNI Echtzeituhr

    Geben Sie hier Zweck der Verwendung dieser Methode für das Rendering? Was willst du tun ?, gibt es große Animation Funktionalität in Android-Engine, kann diese Aufgabe kann mit dieser Animation getan werden.

    Ein weiteres, wenn Sie Codes wie Ihre Batterie des Telefons verwenden werden, laufen auf Null sehr schnell coz das wird cpu / gpu auf max.

    In taskRun = true – versuchen Sie, Blöcke aus laufender Aufgabe zu setzen, setzen Sie bool taskRun = true beim Start und überprüfen Sie, if (!taskRun){ taskRun = true; //here start your task..} if (!taskRun){ taskRun = true; //here start your task..} und auf ui Thread nach dem Update du kannst du auf taskRun = false; wechseln Mit diesem können Sie einige Frames überspringen, aber sollte nicht abstürzen.

    Das Problem ist, dass der Handler des Runnable einen Verweis auf Ihren Runnable . Wenn du dein Runnable zum zweiten Mal laufen Runnable , ist das alte Runnable bereits in der Message Queue , also Task is already in the queue Nachricht. Wenn Sie ein Runnable jedes Mal erstellen, wenn Sie das Runnable wie im Code unten ausführen Runnable , denke ich, dass das Problem gelöst wird.

     public void jniTemporizedCallback(int buf[]) { /* set data to original sized bitmap */ bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight); /* calculate the stretched one */ bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height, false); /* tell the main thread to update the image view */ runOnUiThread(new Runnable() { @Override public void run() { iv.setImageBitmap(bitmapStretched); } }); } 

    Ich denke, du hast recht mit Vernunft, weil du nicht sicher sein kannst, dass Android Bilder in 60 FPS macht. Und ja, ich glaube, du brauchst nur Bitmap Native Callback mit Android Render synchronisieren. So lass uns anfangen.

    Ich bevorzuge die Verwendung von Lock aus Parallelität Stack Java. Weil du siehst, wenn du das Objekt sperrst und wenn du entsperrst. Im Falle der Verwendung von flüchtigen (z. B. Sicherstellen auch Referenzbeschränkungen) auf Bitmap-Objekt, müssen Sie die Sperrung dieses Objekts an sehr Orten, wo Sie mit Bitmap.

    Auch ich denke, du solltest Lock aus diesem Beispiel verwenden (um das Objekt aus irgendeinem anderen Thread zu entsperren). Also, hier ist Beispiel. Beispiel unten funktioniert richtig. Vergessen Sie nicht, Kontext zu löschen und zu stoppen Aufgabe:

     public class MainActivity extends AppCompatActivity { /* Initialize lock (avoid lazy init, with your methods) */ private ReentrantLock lock = new ReentrantLock(); ............ private runnableDrawImage = new Runnable() { @Override public void run() { iv.setImageBitmap(bitmapStretched); lock.unlock(); } }; .......... public void jniTemporizedCallback(int buf[]) { /* synchronize by locking state*/ lock.lock(); bitmapOriginal = Bitmap.createBitmap(///) bitmapOriginal.setPixels(buf, 0, origWidth, 0, 0, origWidth, origHeight); bitmapStretched = Bitmap.createScaledBitmap(bitmapOriginal, width, height,false); MainActivity.this.runOnUiThread(runnableDrawImage); } } 
    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.