๋ชฉ์ฐจ
ANR ์ด์
ANR ๋ฐ์ํ๋ ์ํฉ
- ๋น์ฝ ๋ฐ์ดํฐ ์ค์บ์ด ๋น๋ฒํ๊ฒ ์ผ์ด๋๊ณ , ์ค์บ๋๊ฐ ๊บผ์ง์ง ์๊ณ ๊ณ์ ๋์๊ฐ์ ๋
- ๋ณ๋์ ์ค๋ ๋๋ฅผ ์ง์ ํ์ง ์๊ณ ๊ทธ๋ฅ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฐ์ดํฐ ์ธก์ (์์น, ๋น์ฝ, ์ผ์)๋ฅผ ์ํํ์ ๋
- ๋ก๊ทธ์ธ ์๋ฒ ์์ฒญ ์ ์ง์ฐ์ ๋ฐ๋ฅธ ํ๋ฉด ๋ฉ์ถค
- ๋น๋๊ธฐ์ ์ค๋ ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ตฌ๋ถ ๋ช ํ์น ์์์ด ์์ธ
- ๊ฐ์ ์ข ๋ฃ๊ฐ ๋ฐ์๋จ
- ํ๋ฉด์ด ํ์๊ฒ ๋จ(UI ๋ฉ์ถค) : ๋ก๊ทธ์ธ
Android์ฑ์ UI ์ค๋ ๋๊ฐ ๋๋ฌด ์ค๋ซ๋์ ์ฐจ๋จ๋๋ฉด ANR ์ค๋ฅ๊ฐ ํธ๋ฆฌ๊ฑฐ๋๋ค.
์ ๋ฌธ์ ๊ฐ ๋๋?
- UI ์ ๋ฐ์ดํธ๋ฅผ ๋ด๋นํ๋ ๊ธฐ๋ณธ ์ค๋ ๋๊ฐ ์ฌ์ฉ์ ์ด๋ฒคํธ ๋๋ ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์ฒ๋ฆฌํ์ง ๋ชปํ์ฌ ์ฌ์ฉ์ ๋ถ๋ง์ ์ด๋ํ๋ฏ๋ก ๋ฌธ์ ๊ฐ ๋๋ค.
- ๋๋ ๋ก๊ทธ์ธ ์ค ํ๋ฉด์ด ๋ฉ์ท์ ๋ ๋ค๋ฅธ ๋ฒํผ ํด๋ฆญ ๋ฐ ํ๋ฉด ์๋์ด ๋ถ๊ฐ๋ฅํ ์ํฉ์ด ์ฝ 4์ด๊ฐ ์ง์๋จ์ ๊ฒฝํํ๊ณ ์์ฐ์ค๋ฝ๊ฒ ์ฑ์ ๋๊ฐ๊ฒ ๋์๋ค.
์ธ์ ANR์ด ๋ฐ์ํ๋๊ฐ?
- ์
๋ ฅ ์๋ต ์ง์ฐ
- ์ฌ์ฉ์๊ฐ ํ๋ฉด์ ํฐ์นํ๊ฑฐ๋ ํค๋ฅผ ๋๋ ์ ๋, ์ฑ์ด 5์ด์ด๋ด์ ๋ฐ์ํ์ง ์์ผ๋ฉด ANR์ด ๋ฐ์
- ๋ฉ์ธ ์ค๋ ๋์์ ๋ฌด๊ฑฐ์ด ์์ ์ ์ํ ์ ์ผ์ด๋๋ค.
- ์๋น์ค ์์ ์ง์ฐ
- ์๋น์ค ์์ํ ๋ onCreate, onStartCommand, onBind ๋ฉ์๋๊ฐ ๋น ๋ฅด๊ฒ ์คํ๋์ง ์์ ๋ ๋ฐ์
- ํฌ๊ทธ๋ผ์ด๋ ์๋น์ค ๋ฌธ์
- startForegroundService()๋ก ์๋น์ค๋ฅผ ์์ํ๋๋ฐ, 5์ด ๋ด์ startForeground()๋ฅผ ํธ์ถํ์ง ์์ผ๋ฉด ANR์ด ๋ฐ์ํฉ
- ๋ธ๋ก๋ ์บ์คํธ ๋ฆฌ์๋ฒ ์ง์ฐ
- BroadcastReceiver๊ฐ ์ ํด์ง ์๊ฐ(๋ณดํต 5์ด) ๋ด์ ์์ ์ ์๋ฃํ์ง ๋ชปํ๋ฉด ANR์ด ๋ฐ์ํฉ๋
- JobScheduler ๊ด๋ จ ๋ฌธ์
- JobService์ onStartJob() ๋๋ onStopJob() ๋ฉ์๋๊ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฌ๊ฑฐ๋, ์ฌ์ฉ์ ์์ ์์ ์์ setNotification๋ฅผ ์ ๋ ํธ์ถํ์ง ์์ผ๋ฉด ๋ฐ์
ํด๊ฒฐ๋ฐฉ๋ฒ
- ๋ฉ์ธ ์ค๋ ๋์์ ๋ฌด๊ฑฐ์ด ์์ ์ ํผํ๊ณ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋๋ ์ฝ๋ฃจํด์ ์ฌ์ฉํ์
- ์๋น์ค, ๋ธ๋ก๋์บ์คํธ ๋ฆฌ์๋ฒ,job service ๋ฑ์์ ๋น ๋ฅธ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ํ์ํ๋ฉด ๋ณ๋์ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ์.
์ํฉ
- ๋๋ฃ ๊ฐ๋ฐ์๋ถ์ด ์ง์
จ๋ ๋ก๊ทธ์ธ ๋ก์ง์์ ํ๋ฉด ๋ฉ์ถค ํ์์ด ๋ฐ์ํ๋ค.
- ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ ์๋ฒ์ ์์ฒญ ~ ์๋ต๊น์ง ์ค๋ ์๊ฐ๋์ UI๊ฐ ์ฐจ๋จ๋ ๊ฒ์ด๋ค.
// ๊ธฐ์กด
private fun login(id: String){
val loginRequest = LoginRequest(id)
RetrofitClient.instance.login(loginRequest).enqueue(object : Callback<LoginResponse>{
override fun onResponse(call: Call<LoginResponse>, response: Response<LoginResponse>) {
if(response.isSuccessful){
val loginResponse = response.body()
if (loginResponse?.success == true ){
saveLoginState(true)
val intent = Intent(this@LoginActivity, AdminSettingActivity::class.java)
startActivity(intent)
finish()
}
else{
Log.d("๋ก๊ทธ์ธ", "์ฌ์
๋ ฅ")
}
} else{
Log.d("๋ก๊ทธ์ธ","๋ก๊ทธ์ธ ์คํจ")
Log.d("๋ก๊ทธ์ธ ์ค๋ฅ",response.errorBody().toString())
}
// ํ์ฌ
private fun login(id: String) {
val loginRequest = LoginRequest(id)
CoroutineScope(Dispatchers.IO).launch {
val result = runCatching {
RetrofitClient.instance.login(loginRequest)
}
withContext(Dispatchers.Main) {
result.onSuccess {
if (it.success) {
Toast.makeText(this@LoginActivity, "๋ก๊ทธ์ธ ์๋ฃ", Toast.LENGTH_SHORT).show()
binding.loginButton.isEnabled = true
binding.loginButton.text = "ํ์ธ"
saveLoginState(true)
val intent = Intent(this@LoginActivity, AdminSettingActivity::class.java)
if (PreferenceUtil.getIpAddress(this@LoginActivity) == null) {
Toast.makeText(this@LoginActivity,"IP์ฃผ์๋ฅผ ์ค์ ํด์ฃผ์ธ์", Toast.LENGTH_SHORT).show()
}
startActivity(intent)
finish()
} else {
Toast.makeText(this@LoginActivity, "๋ก๊ทธ์ธ ์คํจ", Toast.LENGTH_SHORT).show()
binding.loginButton.isEnabled = true
binding.loginButton.text = "ํ์ธ"
binding.loginButton.backgroundTintList =
ColorStateList.valueOf(Color.parseColor("#EE675C"))
}
}
result.onFailure {
binding.loginButton.isEnabled = true
binding.loginButton.text = "ํ์ธ"
Log.d("failed login ", "Network error")
Toast.makeText(this@LoginActivity, "๋ก๊ทธ์ธ ์คํจ", Toast.LENGTH_SHORT).show()
}
}
}
}
์ฐจ์ด
- ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์
- Retrofit์ enqueue๋ฅผ ์ฌ์ฉํ ์ฝ๋ฐฑ
- ์ฝ๋ฃจํด์ ์ฌ์ฉํ ๋น๋๊ธฐ ์ฒ๋ฆฌ
- ์๋ฌ ํธ๋ค๋ง
- if-else
- runCatching๊ณผ onSuccess, onFailure์ ์ฌ์ฉ
- ์ค๋ ๋ ๊ด๋ฆฌ
- ๋ช ์์ ์ธ ์ค๋ ๋ ๊ด๋ฆฌ ์์
- Dispatchers.IO์ Dispatchers.Main์ ์ฌ์ฉํ์ฌ ๋ช ํํ ์ค๋ ๋ ๊ด๋ฆฌ
๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฐฉ์
- Retrofit์ enqueue๋ฅผ ์ฌ์ฉํ ์ฝ๋ฐฑ
- enqueue ๋ฉ์๋ ํธ์ถ ์ ๋คํธ์ํฌ ์์ฒญ์ด ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ์คํ๋๋ค.
- ์ฝ๋ฐฑ ์ธํฐํ์ด์ค์ onResponse๋ onFailure ๋ฉ์๋๋ฅผ ํตํด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์
- ์ฅ์
- ๊ฐ๋จ & ์ง๊ด
- ๋จ์
- ์ฌ๋ฌ ๋น๋๊ธฐ ์์ ์ ์ฐ๊ณํ๊ฑฐ๋ ๋ณต์กํ ๋ก์ง ์ค๊ณ ์ ์ฝ๋ฐฑ ์ง์ฅ์ ๋น ์ง ์ ์์
- ์ฝ๋ฃจํด์ ์ฌ์ฉํ ๋น๋๊ธฐ ์ฒ๋ฆฌ
- suspend ํจ์๋ฅผ ํตํด ๋น๋๊ธฐ ์์
ํํ
- suspend ํจ์์ ์๋ฏธ
- launch ๋๋ async๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๋ฃจํด์ ์์
- suspend ํจ์๋ฅผ ํตํด ๋น๋๊ธฐ ์์
ํํ
์ค๋ ๋ ๊ด๋ฆฌ
- Retrofit์ enqueue๋ ์์ฒด์ ์ผ๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋์์ ๋คํธ์ํฌ ์์
์ ์ํ
- ์ฝ๋ฐฑ ๋ฉ์๋๋ ๋ฉ์ธ ์ค๋ ๋์์ ์คํ๋จ
- ์ฝ๋ฃจํด
- Dispatchers.IO : I/O ์์ ์ ์ต์ ํ๋ ์ค๋ ๋ ํ์ ์ฌ์ฉ, ๋คํธ์ํฌ ์์ฒญ์ด๋ ํ์ผ ์์
- Dispatchers.Main : ๋ฉ์ธ ์ค๋ ๋์์ ์์ ์คํ, UI ์ ๋ฐ์ดํธ์ ์ฌ์ฉ
- withContext(Dispatcher.Main) : ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ์ธ ์ค๋ ๋๋ก ์ ํ
๋ฐ์ดํฐ ์ ์ฅ ์์น
- ๋ ํธ๋กํ enqueue ์ด์ฉ ์ฝ๋
- ๋ฉ์ธ ์ค๋ ๋์์ saveLoginState ํธ์ถ ์ค
- ์ฝ๋ฃจํด ์ด์ฉ ์ฝ๋
- ๋์ผํจ์ ํ์ธ ํ ์์
- IO ์ค๋ ๋์์ ์คํ๋๋๋ก ์์
- ๋์ผํจ์ ํ์ธ ํ ์์
728x90
'๐ค2024 ์๋๋ก์ด๋ > โ๏ธ ํ๊ณ ์ธํด ๊ฐ๋ฐ ํ๋ก์ ํธ ๊ธฐ๋ก' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
โบ๏ธ ์ธํด ๊ฐ๋ฐ์ผ์ง ๋ชจ์ (1) | 2024.12.17 |
---|---|
11์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
10์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
9์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |
8์ฃผ์ฐจ ๊ฐ๋ฐ์ผ์ง (0) | 2024.12.17 |