2017년 4월 18일 화요일

[android] Thread 와 aSyncTask, Handler ..삽질하며 배운내용..

우선 책은 일절 참조하지 않은상태에서 작성했던 내용을 토대로 정리한것이므로, 정확하지도, 어쩌면 틀릴 가능성이 매우 높으니. 나처럼 지식이 전무한 사람들이  보고 어디부터 어떻게 시작할지 감이라도 잡히길 바라며 남기는 노트입니다.





안드로이드에서 메인 쓰레드는 이미 존재한다, 당연하게도 우리는 main 보지 못하고, MainActivity 클래스에서 onCreate 함수가 시작점 이라는것을 짐작해서 알고있으니, 어디선가 main함수가 있긴 있었다는 이야기가 된다.

메인 Thread 안드로이드의 UI 총괄적인 담당을 맡고있다, 이런 이유에서 우리는 함부로 UI Thread 건드리지 않는것을 권장받는다. 이를 건드릴시, 딜레이나 작동오류 따위의 퍼포먼스부터 실행까지 중대한 문제가 발생할 가능성이 높다.

이미 UI관련으로 많은 작업을 main Thread 맡고 있는 이유덕분에,  우리는 이곳에서 추가적인 Thread 필요한 작업들을 없게 접근제한을 당한다. Eg) socket통신.

이러한 문제를 해결하기위해 우리는 Annonymous Class따위나 신규 class 이용해 새로운 Thread/Runnable 생성할 있는데, 케이스에 따라서 매우 만족스럽지 못한 사태가 발생하던데, main Thread에서 모든 점유율을 가지고있는 사태가 발생한다. 똑바로 작동을 하지 않았었다.

여기서 나는 Thread 우선순위 조정이나, sleep 시도할까 했지만, 앞서 언급된 UI Thread 건드리는것은 중대한 퍼포먼스 이슈를 야기할 있다는 경고덕분에, 그만두기로 마음먹었다.

그렇다면 어떻게 Thread 이용하나 고민하는데, 몇가지 방법이 있는데 내가 들은것은 handler  AsyncTask 라는 기본 제공 API 있다는 이야기를 접했다.

AsyncTask 일종의 Thread Haandler 역활을 모두 담당 관리 해주는 놈인거 같은데,
해당 클래스는
1 : 추상클래스
2: 기본제공 메소드는 (아마)4가지
3: 각각의 메소드의 타입을 미리 정해야 한다<Void,Void,Void>리턴타입이 없다면 Void 쓰는듯 하다.     
     (primitive type 안먹히는듯 하다. Refrence type 가능하다)

기본제공 메소드는:
1.doInBackground() 실행 메소드 이안에서 작업내용을 준비하는듯 하며
2.onProgressUpdate() 다음 메소드가 자동적으로 호출된다 이는 사용자에게 진행을 알릴떄에 사용
3.onPostExecute()  백그라운드 작업이 종료되면 호출되어 결과를 뽑아냄
4.onPreExecute() 마치 생성자 같은놈 인듯 하다. aSyncTask 실행하기 전에 호출되는듯 하다.
있다.

그리고 생성한 aSyncTask .execute() 하면 작동한다.

이때 한가지 발견한 문제점이, aSyncTask 1 execute 있다. 두번째 실행에서 오류를 뿜으며 프로그램이 종료되는것을 확인 있었다.
해결방안은 여라가지 있겠지만 당장 생각나는것은, 매번 새롭게 class 선언 실행, 다른거 쓰기
정도가 있지 않을까 한다.

쓰레드들이 여러 선언되어 동작하고 있어도 쓰레드들은 결국에는 독립적인 존재임은 자바 쓰레드 기초정도만 알아도 이해 있다.(해결하기위해 synchronization등을 썻지) 이러한 이유때문에, 메인 쓰레드가 아닌곳에서 무엇인가 정보의 업데이트가 이루어진들, UI 변화가 없는것은 당연한 일이다.

그런 문제를 해결하기 위해 Thread 함꼐 붙어있는 Handler 필요하게 된다.

Handler Thread간의 연결에 필요한 기능인데,
주로 UI 화면 업데이트에 매우 긴밀한 연관이 있는듯 하다.

Handler.sendMessage() ->개발자 정의 쓰레드에서 호출하고, 메시지 큐에 메세지를 저장한다.
Handler.handleMessage()-->UI쓰레드에서 호출하여 Queue 저장된 메세지를 뿌려, UI 업데이트 하는 방법이다.

지금까지 알아본 바로는 handler 사용자즹어 쓰레드간의 연결이 아닌 UI 사용자정의 쓰레드 간의 연결인듯 하며, 핸들러가 있지 않아도, 작동에는 문제가 없다. 다만 어렵거나 매우 재한적이겠지.

사용법은 MainActivity에서 handler extends 이너클래스를 생성 한다.
이너클래스에서는 handleMessage() 메소드를 만들며, android.os.Message 작동할 상황을 정해서 case문처럼 있는듯 하다. 이제 handlemessage 작업내역을 작성하고 실행하는듯하다.

댓글 없음:

댓글 쓰기