Android SurfaceView Verständnis

H

HansP

Gast
Hi!

Ich möchte die SurfaceView Klasse und das SurfaceHolder.Callback Interface nutzen, um auf mein Android Handy zu malen :)
Ich habe dazu auch ein funktionierendes Beispiel, aber ich weiß nicht so recht, warum dieses funktioniert. Ich möchte das ganze Beispiel hier ungern zeigen, weil es nicht von mir ist, aber ich werde es einmal in Stichworten/Codestücken beschreiben und dazu Fragen stellen.

1. Haben wir eine Klasse "Male":
Java:
public abstract class Male extends SurfaceView implements SurfaceHolder.Callback {

	MalThread mThread;

	public PaintBox(Context context) {
		super(context);
		getHolder().addCallback(this);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		mThread = new MalThread(getHolder(), this);
		mThread.setRunning(true);
		mThread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
	   // beende mThread
	}

	@Override
	protected abstract void onDraw(Canvas canvas);

}
Durch SurfaceView stellt die KLasse doch die Oberfläche zum Malen bereit. Dadurch, dass wir uns beim SurfaceHolder registrieren, werden wir über Veränderungen der Oberfläche (surfaceDestroyed, ..) informiert. Im Konstruktor bekommen wir einen Context, dazu komme ich in späteren Posts vermutlich nochmal.

2.
Java:
class MalThread extends Thread {
	private SurfaceHolder surfaceHolder;
	private Male male;
	private boolean running= false;

	public MalThread(SurfaceHolder surfaceHolder, Male m) {
		this.surfaceHolder = surfaceHolder;
		this.male= m;
	}

	public void setRunning(boolean run) {
		running= run;
	}

	private int height = -1;
	private int width = -1;

	Bitmap buffer = null;
	Canvas bufferedCanvas = null;

	@Override
	public void run() {
		Canvas c;

		while (running) {
			if (height != -1 && width != -1 && bufferedCanvas != null)
				male.onDraw(bufferedCanvas);

			c = null;
			try {
				c = surfaceHolder.lockCanvas();
				synchronized (surfaceHolder) {
					if (c != null) {
						
						if (bufferedCanvas == null || buffer == null || c.getWidth() != width
								|| c.getHeight() != height) {
							width = c.getWidth();
							height = c.getHeight();
							buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
							bufferedCanvas = new Canvas(buffer);
						}
						c.drawBitmap(buffer, 0, 0, null);
					}
				}
			} finally {
				if (c != null) {
					surfaceHolder.unlockCanvasAndPost(c);
				}
			}
		}
	}

}
Hier verstehe ich nicht so richtig, was passiert. Der MalThread läuft ja nun unabhängig los, und was genau tut er? Wieso gibt er "bufferedCanvas" an male.onDraw() weiter? Wieso ist das "the Canvas on which the background will be drawn"? Ich dachte, die Oberfläche wird von SurfaceView bereit gestellt? Was genau passiert danach?

Ich denke das sind erstmal genug Fragen. Vielleicht komme ich danach ja auch schon alleine zurecht :)

Gruß,
Hans
 

schlingel

Gesperrter Benutzer
Der Code der das Bitmap auf den Schirm zeichnet sitzt nach wie vor noch in der View-Klasse bzw. in der Canvas-Klasse. (Die View stellt das Canvas dar)

Allerdings wird das nicht im UI-Thread ausgeführt sondern im MalThread.
 
H

HansP

Gast
Hallo Schlingel und Danke für deine Antwort!

Leider hilft mir diese aber nicht so richtig weiter. Welches Bitmap meinst du genau? Welche View-Klasse? "Male" weil sie SufraceView erweitert? Ich verstehe aber auch nicht genau, wie mir das helfen soll.

Ich versuche nochmal präzisere Fragen zu formulieren:

1. Was ist bufferedCanvas? Ist das so eine Art Hintergrund?
2. Wieso ist male.onDraw vor dem lockCanvas? Ich dachte das Malen muss immer zwischen lockCanvas und unlockCanvasAndPost liegen.
 

Ähnliche Java Themen

Neue Themen


Oben