Canvas wird nicht gezeichnet?

A

Arif12

Neues Mitglied
Threadstarter
Hallo, in meiner App soll ein Koordinatensystem gezeichnet werden. Dieser soll mit dem Finger bewegt werden können. Da es ziemlich lange dauert das Koordinatensystem zu zeichnen, erstelle ich ein Bitmap und speichere das gezeichnete Koordinatensystem dort ab.
Code:
new Thread(new Runnable() {
    @Override
    public void run() {
        while (!ks.drawed);
        bitmap = Bitmap.createBitmap(ks.getWidth(), ks.getHeight(), Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);
    }
}).start();
Nach jeden Touch-Event rufe ich folgenden Code auf, um das KS zu zeichnen
Code:
ks.draw(canvas);
Die onDraw()-Implementierung des Koordinatensystems
Code:
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (!drawed) {
        if (p == null) p = new Paint(Paint.ANTI_ALIAS_FLAG);
        drawAchsen(canvas, p);
        drawGraphen(canvas, p);
        drawed = true;
    }
}
Die onDraw()-Methode zeichnet das Koordinatensystem nur einmal.
Das ganze funktioniert auch nur bis ich z.B. die Hometaste drücke oder die App pausiere, denn der Canvas wird nicht mehr gezeichnet, obwohl die View sichtbar ist und nicht verschoben wurde.
 
swa00

swa00

Moderator
Teammitglied
Hallo und willkommen im Forum ,

Auf Anhieb kann ich nur vermuten, dass du den LifeCycle nicht richtig umsetzt.
Sobald du dann von Dir aus ein invalidate setzt, müsste die OnDraw triggern

Was sagt denn dein STepBySTep Debugging ?


P.S: Dein runnable ist aber ziemlich abenteuerlich, kann auch an dem liegen, wenn du dein block-Flag nach dem Lifecycle nicht richtig setzt.

P.S.2
Code:
 while (!ks.drawed);
Geht unter Android gar nicht - Die UI benötigt Luft zum Arbeiten :)
 
Zuletzt bearbeitet:
A

Arif12

Neues Mitglied
Threadstarter
Durch die while-Anweisung wartet der Thread bis das Koordinatensystem einmal gezeichnet wurde. Das Semikolon steht für eine leere Anweisung. Die while-Schleife "tut" also nichts. Nachdem das Koordinatensystem gezeichnet wurde, wird der block-Flag für "immer" auf false gesetzt. Anschließend wandle ich das Koordinatensystem mit den folgenden Anweisungen in ein Bitmap um.
Code:
bitmap = Bitmap.createBitmap(ks.getWidth(), ks.getHeight(), Bitmap.Config.ARGB_8888);
                canvas = new Canvas(bitmap);
Die onDraw()-Methode in Koordinatensystem tut auch nichts sinnvolles, wenn der block-Flag nicht gesetzt ist. Das soll auch so sein, weil Koordinatensystem den Bitmap zeichnen soll. Das ganze funktioniert auch so wie es soll, aber wenn ich z.B. die Hometaste betätige, verschwindet das Koordinatensystem. Die View (Koordinatensystem) ist nicht das Problem. Die View ist weiterhin sichtbar und wurde nicht verschoben. Das Canvas und die Bitmap werden in Instanzvariablen gespeichert. In der Activity rufe ich
Code:
ks.draw(canvas);
auf, um die Bitmap zu zeichnen. Was meinst du mit Lifecycle?
 
swa00

swa00

Moderator
Teammitglied
Durch die while-Anweisung wartet der Thread bis das Koordinatensystem einmal gezeichnet wurde.
Es ist schon klar , was du damit erreichen möchtest - das musst du nicht erklären,
aber sowas kannst du nicht unter Android anwenden.

a) So etwas blockiert dir u.U. den kompletten UI Thread (So sieht es auch derzeit danach aus)
b) ich würde das in einem AsyncTask umsetzen und in einem separaten UI-Runnable dein Bitmap ermitteln
c) Und vor allem delays verwenden, wenn du schon warten möchtest
d) Allerdings statt einem Flag, eher einen Custom Listener verwenden Creating Custom Listeners | CodePath Android Cliffnotes

LifeCycle = Basisvoraussetzung für Apps:
Understand the Activity Lifecycle | Android Developers

Nochmal die Nachfrage , was sagt dein Debugging ?
 
Zuletzt bearbeitet:
A

Arif12

Neues Mitglied
Threadstarter
b) AsyncTask kann ich nicht verwenden, weil ich auf das Koordinatensystem zugreifen muss und nur der UI-Thread auf Views zugreifen darf.
c) Ich weiß doch nicht wie lange ich warten muss, deshalb habe ich einen Flag benutzt.
d) Die Idee mit den Custom Listener hört sich gut an.
Wollen Sie, dass ich die Debuggingsausgaben hier posten soll?
 
swa00

swa00

Moderator
Teammitglied
AsyncTask kann ich nicht verwenden, weil ich auf das Koordinatensystem zugreifen muss und nur der UI-Thread auf Views zugreifen darf.
Doch , du kannst sehr wohl zugreifen - Bsp :
Code:
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            btn.setText("Irgendwas"); <------   Hier  wird auf ein UI - Element zugegriffen
                        }
                    });


Ich weiß doch nicht wie lange ich warten muss, deshalb habe ich einen Flag benutzt.
Das ist eher dann eine Try & Hope programmierung
Deshalb einen AsycnTask und wenn der komplett fertig ist , erst dann ein Refresh.


Wollen Sie, dass ich die Debuggingsausgaben hier posten soll?
Der nutzt nichts , denn du hast ja keinen ABsturz , sondern einen kritischen Laufzeitfehler.
Du solltest für Dich selbst ein Step by Step Debugging machen , um zu schauen , wo er hängt .


Aber ohne ein vernünftiges LifeCycle handling wirst du eh deine Probleme bekommen .
Im Falle des Homebuttons , geht die App in den Ruhezustand und verliert den Focus auf den View
Das musst du abfangen.
 
Zuletzt bearbeitet:
J

jogimuc

Erfahrenes Mitglied
Hallo

Ich gehe mal davon aus das du dir eine Klasse von View oder Imageview abgeleitet hast . denn sonst hättest du keine onDraw Methode. Und hast bestimmt auch in deine Activity eine View davon erstellt.

Nur ruft man die onDraw nicht direckt auf wenn sie neu gezeichnet werden soll.

Ist nicht so sinnig.
ks.draw(canvas);


da würde ich ks.postinvalidate() benutzen und in der onDraw würde ich das Bitmap auf das Canvas setzen. Was ja der Methode auch übergeben wird.
 
Jaiel

Jaiel

Experte
Also bin nicht mehr so auf der Höhe mit Android aber ich hab immer SurfaceView benutzt für solche vom MainThread losgelösten Zeichensachen. Einfach einen Thread ausserhalb des UI Thread benutzen um den Life-Cycle der SurfaceView zu steuern...

(und nebenbei bitte nicht englische Namen mit deutschen mischen sieht grausig aus drawAchsen() zu lesen zum Beispiel :D )
 
Thread starter Similar threads Forum Replies Date
H Android App Entwicklung 3
Oben Unten