[안드로이드 게임 개발] Thread
일반적인 어플을 만들때에는 스레드를 쓰지 않아도 어느정도는 개발이 가능하지만, 게임에서는 필수입니다. 일반 어플리케이션에서는 메인 스레드에서 거의 모든작업을 진행되지만, 게임에서처럼 지속적인 처리와 관련된 처리는 지원하지 않습니다. 스레드는 특정 작업을 분산시켜서 작업하는 것이라고 생각하면 되는데요. 에제를 만들어가면서 이해해 보도록 하겠습니다.
■ 두개의 아이콘이 한 화면에서 위,아래로 움직이는 프로그램을 만들어보도록 하겠습니다. 먼저 프로젝트를 생성하고, 뷰 클래스를 상속받은 스레드 클래스를 만들어서 다음과 같이 기본 코딩을 하겠습니다.
■ 다음으로 이미지 두개를 화면에 배치하도록 하겠습니다.
■ 위의 소소대로 코딩을 해서 AVD에 아이콘 두개를 배치해봤습니다. 이제 이 두 아이콘이 위쪽으로 왕복을 하게 할겁니다. 그럴려면 애플리케이션에 입력이 없어도 지속적으로 호출되는 메서드가 필요한데요. 안드로이드의 UI스레드는 자신의 일만 처리합니다. 그렇기 때문에 지속적으로 입력이 없어도 계속 아이콘들을 움직여줄 스레드가 따로 필요합니다. 안드로이드에서는 이것을 지원하지 않기 때문에 자바 스레드를 이용해야 합니다.
■ 첫번째 아이콘을 움직여줄 클래스를 스레드를 상속받아서 만들도록 하겠습니다.
run()메서드에서 실제로 스레드가 처리할 내용을 정의하게 됩니다.
■ 다음으로 메인스레드에서 start()메서드를 호출해서 스레드가 독립적으로 동작하게 합니다.
■ 위와 같이 strart()메서드가 실행되는 순간 Move1가 생성되어 그 스레드에서 run()메서드가 실행되게 됩니다. 현재 run()메서드에는 아무것도 없기 때문에 호출되었다가 바로 반환됩니다. Thread의 겨우 run()메서드가 종료되면 소멸됩니다. 그러므로 run()메서드에 루프롤 넣어서 계속해서 왕복하도록 코딩을 해야 합니다.
■ ThreadExample클래스에 있는 높이값(public int floor1=0;)을 Move1에서 조작할 수 없으므로 Move1의 생성자로 ThreadExample 값을 넘겨 받게 하여 왕복하도록 코딩을 해주겠습니다.
■ 여기까지는 스레드 클래스를 상속받아 스레드를 실행하는 방법입니다. 아직은 실행해도 화면에 아무런 변화가 없습니다.
■ 두번째 아이콘은 Runnable 인터페이스로 구현해 보겠습니다.
■ 다음으로 메인 스레드에서 Runnable을 사용해서 스레드를 생성합니다.
■ 위의 두가지 방법으로 스레드를 생성할 수 있습니다. 두가지의 방법은 각각의 특징과 장단점이 있는데요. 첫번째 방버은 스레드 클래스를 상속받아서 스레드 클래스 내부의 메서드를 바로 사용할 수 있어서 관리하기가 편하지만 다중 상속이 되지 않기 때문에 다른 클래스를 상속받을 필요가 없을때만 사용할 수 있습니다.
■ 두번째의 경우는 이미 상속받은 클래스를 스레드화 할 때 사용하면 유용하지만 이 방법은 스레드 클래스의 메서드를 이용할수 없다는 단점이 있습니다.
■ 게임을 만들때에는 첫번째 방법을 많이 사용합니다. 게임 개발에서는 스레드를 상속한 클래스가 다른 클래스를 상속받을 일이 거의 없기 때문입니다.
■ 여기까지 진행을 하고 어플을 실행해봐도 아무런 변화가 없습니다. 화면을 갱신해주는 invalidate()메서드를 호출해서 해결할 수 있습니다. 안드로이드에서는 view가 생성되면 그 view를 생성한 스레드만 해당 view에 접근할 수 있습니다. 때문에 view.postInvalidate()메서드를 호출해서 UI 스레드에 갱신 요청을 해서 위에서 만든 스레드에서 view화면을 갱신하는 방법을 사용해야 합니다.
■ 또하나, 스레드가 실행되면 우리 눈으로 확인이 안될정도로 빠르게 실행이 되버립니다. 그래서 화면을 갱신하고 나면 어느정도 대기 시간을 두어 왕복하는 것이 눈에 보이게 해주어야 합니다.
대기 시간을 줄때는 다음과 같은 코드를 사용합니다.
try{
Thread.sleep(대기시간);
}catch(InterruptedException e){}
■ 위의 메서드는 try~catch구문과 함께 사용해야 컴파일 시 에러가 발생하지 않습니다. 그 이유는 Thread.sleep()메서드를 호출하면 자바의 스레드 스케줄러에 의해 run상태인 스레드가 wait 상태로 바뀔 때 예외가 발생하면 InterruptedException을 던져주기 떄문에 이 예외를 try~catch구문에서 해결해 줘야 합니다. 그리고 이 메서드의 인자는 밀리 초(ms)단위로 받습니다. 1000ms=1초 입니다.
■ 이제 최종 코딩을 마무리 하고 어플을 실행 해 보겠습니다.
■ 이번 포스팅에서의 과정만 실행을 해보면 두개의 아이콘이 동시에 움직이는데요. 다음 포스팅에서는 랜덤값을 생성해서 두개의 아이콘이 다른 속도로 움직이는 과정을 살펴보겠습니다.