Rysowanie wewnątrz funkcji run()

0

Witam. Piszę aplikacje na Androida. Chciał bym napisać kod, który rysuje coś w osobnym wątku.Dobrze było by użyć czegoś w rodzaju drawable.
Nie wiem jak się za to zabrać. Nie mogę tu chyba przeciążyć funkcji onDraw().
Wszelkie próby konstrukcji z canvas, drawable i draw() nie chcę mi wychodzić.

Z góry dziękuje za pomoc :)

0

Ale gdzie chcesz to rysować? Jeśli dobrze cię rozumiem to:

  1. Tworzysz klasę rozszerzającą View i tam modyfikujesz onDraw()
  2. Do Layout po którym chcesz malować dodajesz ten View
  3. W wątku wywołujesz metody na tym swoim View
0

Oki zrobiłem coś takiego:


	public class myView extends View{

		public myView(Context context) {
			super(context);
			
	        MainThread thread = new MainThread();
	        thread.go();
		}
		
		@Override
		public void onDraw(Canvas canvas){
			super.onDraw(canvas);

		}
		
		//klasa obsługująca główny wątek
		public class MainRunnable implements Runnable{
			public void run() {  
				//tutaj malowanie pierwszej rzeczy
			}
		}
		
		//wątek dla głównej pętli
		public class MainThread{
			public Thread t = new Thread(new MainLoop());
			void go(){
				t.start();
			}
		}

	//dalej gdzieś tam drugi wątek rysujący inną rzecz
	}

Oki i teraz sobie coś tam pisze w onDraw. Tylko chciał bym napisać 2 wątki, jeden rysuje jedną rzecz, a drugi zupełnie inną i nie mam pojęcia jak to rozwiązać.

Jak robię jakiś wielki błąd to proszę o podpowiedź :)

0

A nie mozesz dodać drugiego view na którym malujesz coś drugiego?

0

Ano mogę. Klasa view jest wewnątrz klasy głównej która wychodzi z Activity. Używam w onCreate() funkcji setContentView(new GameView(getBaseContext()) );
Nie wiem czy robię dobrze. Jak wtedy użyć do mojego layoutu obrazka z obu view?

1

Layout ma metodę addView()

1
  1. Wszelkie rysowania na View można wykonywać WYŁĄCZNIE w głównym wątku w metodzie onDraw, bo te operacje nie są w jakikolwiek sposób synchronizowane. Jeśli masz coś co wymaga przy rysowaniu skomplikowanych obliczeń to przenosisz tylko te obliczania do innego wątku. Można np rysować na jakiejś bitmapie i tą bitmapę rysować od czasu do czasu na View.
  2. Jeśli tworzysz własny widok to jest on bez problemu dostępny w edytorze layout-u, więc nie musisz kombinować przez ręczne dodawanie
0

Oki, dzięki, rysuje mi już fajnie, problem teraz mam taki, że jak odpalam sobie wątek do operacji na rysowanych obiektach (tak jak napisałeś):

		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(new MainLoop() );

i wchodzę do wątku, to gdy napisze tak:

		public class MainLoop implements Runnable{
			public void run() {
				obiekt.setAlpha(0);
				obiekt.setAlpha(255);
			}
			
		}

To oczywiście obiekt będzie widoczny, jak gdyby zostały wykonane obie funkcje. Natomiast gdy chcę zrobić zwłokę czasową (coś w stylu animacji pojawia się i znika) w taki sposób:

		public class MainLoop implements Runnable{
			public void run() {
				try {
					obiekt.setAlpha(0);
					TimeUnit.SECONDS.sleep(2);
					obiekt.setAlpha(255);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
			}			
		}

To po włączeniu aplikacji obiekt jest niewidoczny a po 2 sekundach nic się nie dzieje (po 10 też nie :) )
Zastanawiam się co robię źle.

(setAplha jest tu akurat dlatego,że próbowałem zamiennie z setVisible)

1

Z dokumentacji wynika, że exec.execute nie daje gwarancji na to, że ten Runnable MainLoop (tragiczna ta nazwa) wykona się w innym wątku. Jeśli ci się wykonuje w wątku głównym to po prostu aplikacja ci zwisa.

Radzę byś zajrzał do przykładów androida "Moon lander" i "Snake" jeśli dobrze pamiętam. Trochę naprostują ci się pomysły jak to robić.
Na dodatek po co tak kombinujesz! Android dostarcza API do prostych animacji: http://developer.android.com/guide/topics/graphics/prop-animation.html .

0

Dzięki, tylko teraz pojawił się nieprzewidziany problem. Pracuje na telefonie Samsung Galaxy S Advance który ma wersje systemu 2.6 czyli api 10 a to co Ty podałeś z tego co widzę jest od api11 :/

1

no to trzeba było przeczytać dokładniej bo tam jest też link do starszego gorszego API (level 1) http://developer.android.com/guide/topics/graphics/view-animation.html http://developer.android.com/reference/android/view/animation/Animation.html

0

W programie LunarLander do obliczania zwłoki czasowej został użyty czas systemowy pobierany za pomocą System.currentTimeMillis();
Czy to jest dobre rozwiązanie, czy istnieje jakieś lepsze? :)

Edit: Użyłem SystemClock.currentThreadTimeMillis(); myślę że to będzie bardziej wiarygodne.

0

Pojawił się nagle pewien ciekawy problem, z którym nie mogę sobie poradzić. Chodzi o to, że na osobnym wątku rysuje wszystko, a w głównym jest ta magiczna metoda onTouch() którą pobieram pozycje kliknięcia i na tej podstawie sprawdzam czy kliknięto w obiekt który jest widoczny. I dzieje się coś takiego, że oba wątki (główny i rysujący) działają bez żadnej synchronizacji i zdarza się, że klikam na dany obiekt, który jest widoczny a punkty nie są zaliczane.

Prosił bym, żeby ktoś mi podpowiedział jak zsynchronizować oba wątki aby po kliknięciu w widoczny obiekt zaliczane były punkty od razu.

Z góry dziękuje :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1