Android 비동기화

정삼빈·2021년 7월 1일
0

Android

목록 보기
3/4

글을 쓸 땐 제목부터 써놓자... 다른페이지 뒤로가기 눌렀는데 여기서 뒤로가기 눌려져서 다 날라가지 않도록,,,,

Thread

모든 코드는 위에서 아래로 순차적으로 진행된다(동기식)
여러 작업을 비동기적으로 처리하기 위해 Thread 사용
작업 여러 개를 번갈아 가면서 처리하여 동시에 처리하는 것처럼 보임
a.k.a 일반 thread, 개발자가 만든 thread, worker thread, 작업자 스레드

Main Thread

Activity의 코드를 처리하기 위해 안드로이드 OS는 thread를 발생시키는데 이것을 Main Thread(UI Thread)라고 함
Main thread가 작업을 하지 않을 때만 화면 작업이 가능

ANR (application not respond, 응답없음)

Main Thread가 바쁠 때 touch나 화면 작업 발생 시 ANR 발생 가능
ex) onCreate에서 무한루프 돌려놓기,,

⚠ 주의 ⚠

안드로이드 오레오(8.0) 미만에서 thread에서 화면에 대한 처리를 하면 오류가 발생
8.0 이상부터는 개발자가 발생시킨 thread에서 화면 처리 가능
-> 안드로이드 OS가 발생시킨 main thread가 처리하도록 넘겨 버림

⚠ 주의 2 ⚠

네트워크 통신을 포함한 5초 이상 소요되는 작업을 Main Thread에서 처리 시 ANR 발생 가능
-> 일반 thread에서 처리

Handler

✅ Main Thread에서 처리하는 코드 중 일정 작업을 계속 반복 처리해야하는 경우
✅ Thread 작업 중 화면 처리 (안드로이드 8.0 미만)
Handler를 통해서 안드로이드에게 요청하여 이부분의 코드를 Main Thread에게 처리해달라고 요청
안드로이드 OS(Main Thread)가 한가할 때 이 작업 처리
중간중간 쉬는 타임이 생기는데 이때 화면 작업 처리
핸들러를 사용하면 특정 코드를 메인 쓰레드로 하여금 반복해서 작업할 수 있다

반복 작업 예시

class MainActivity : AppCompatActivity() {
	val handler : Handler? = null
	override fun onCreate(savedInstanceState: Bundle?){
    	super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        handler = Handler()
        
        val thread = ThreadClass()
        handler?.post(thread)
    }
    inner class ThreadClass: Thread() {
    	override fun run() {
        	handler?.post(this)
        }
    }
}

화면 처리 예시

class MainActivity : AppCompatActivity() {
	val handler : Handler? = null
	val isRunning = false
	
    override fun onCreate(savedInstanceState: Bundle?){
    	super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        handler = DisplayHandler()
        isRunning = true
        
        val thread = ThreadClass()
        thread.start()
    }
    
    inner class ThreadClass: Thread() {
    	override fun run() {
        	while(isRunning) {
            	handler?.sendEmptyMessage(0)
            }
        }
    }
    
    inner class DisplayHandler: Handler() {
    	override fun handleMeassage(msg: Message) {
        	// 화면 작업
        }
    }
    
    override fun onDestroy() {
    	super.onDestroy()
        isRunning = false
    }
}

중간 요약

Main Thread가 처리하는 코드가 5초 이상 걸리면 ANR 발생 강제 종료 되는 경우도 있음
문제 : 일반 Thread에서는 화면에 대한 처리가 불가능(Android 8.0 미만)
-> 일반 Thread를 쓰다가 화면에 관련된 처리는 Handler를 이용하면 됨

Handler는 5초 미만의 빨리 끝나는 작업반복하고 싶을 때
시간 상관없이 계속해서 작업하는 것은 Thread(네트워크 관련 처리, 5초 이상 걸리는 작업)
Thread 작업 중 화면처리가 필요한 건 Handler ( Main Thread가 작업)

AsyncTask

주의 Android 11(API 수준 30)에서 deprecated

Couroutine 사용 권장

비동기처리를 위해 제공되는 클래스
개발자가 발생시키는 Thread와 Handler의 조합으로 Thread 운영 중 화면 처리가 가능했던 구조를 클래스로 제공
AsyncTask를 사용하면 개발자가 발생시키는 일반 쓰레드와 화면 처리를 위해 Main Thread를 이용하는 것을 조합하여 작업이 가능

4가지 메소드를 오버라이드해서 사용

onPreExecute

doInBackground 메서드가 호출되기 전에 호출되는 메소드
Main Thread가 처리

doInBackground

새로운 Thread 발생(일반 Thread)

onProgressUpdate

doInBackground 메서드 내에서 화면 처리가 필요할 때 사용

onPostExecute

메서드 수행 완료 후 호출
Main Thread가 처리

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?){
    	super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val async = AsyncTaskClass()
        async.execute()
    }
    
    inner class AsyncTaskClass: AsyncTask <Int, Long, String>() {
    	override fun onPreExecute() {
        	super.onPreExecute()
        }
        override fun doInBackground(varag p0: Int?): String {
        	return ""
        }
        override fun onProgressUpdate(varag values: Long?) {
        	super.onProgressUpdate(*values)
        }
        override fun onPostExecute(result: String?) {
        	super.onPostExecute(result)
        }
    }
}

AsyncTask <Params, Progress, Result>

  • Params : doInBackground의 parameter type, execute 메소드 인자 값
  • Progress : onProgressUpdate의 parameter type
  • Result : doInBackground의 return 값, onPostExecute의 parameter type
profile
studying android ..

0개의 댓글