안드로이드는 기본적으로 싱글 스레드를 갖는다.
그리고 별도의 설정을 하지 않는다면 동일 프로세스의 동일 스레드에서 실행된다.
어플을 실행하면 안드로이드 시스템이 어플에 대한 쓰레드를 생성하는데 이를 메인쓰레드라고 한다.
메인 쓰레드는 안드로이드 UI와 어플리케이션이 상호작용하는 쓰레드라서 MainThread = UI Thread라고 부르기도 한다.
앞서 언급한 것 처럼 안드로이드의 컴포넌트들은 기본적으로 UI Thread에서 시작되기 때문에 시스템 콜백에 응답하는 메소드 또한 항상 UI Thread에서 실행된다.
그래서 시간이 많이 걸리는 네트워크DB다 리소스를 많이 잡아먹는 작업은 Worker Thread라는 새로운 쓰레드를 생성해서 작업한다.
이러한 작업을 처리하는 대표적인 방법은 2가지이다.
쓰레드와 쓰레드간의 통신을 엮어주는 방법이다.
Handler와 AsyncTask
이번 토이프로젝트의 경우 Looper를 이용했다.
몇초 이후에 특정 메소드가 실행되어야 했다.
class DiaryActivity : AppCompatActivity() {
//MainThread에 연결된 handler생성
private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_diary)
val diaryEditText = findViewById<EditText>(R.id.diaryEditText)
val detailPreferences = getSharedPreferences("detail",0)
//SharedPreference에 저장되어있는 글을 불러오는 공간.
diaryEditText.setText(detailPreferences.getString("detail",""))
//아래 람다가 한글자마다 실행되는 것을 막기 위하여 쓰레드 활용 Runnable Interface구현
val runnable =Runnable{
getSharedPreferences("diary",0).edit{
putString("detail",diaryEditText.text.toString())
}
}
//Text가 변화될때마다 안의 람다가 실행된다.
//handler를 이용하여 0.5초 마다 runnable을 실행하게 만들어 놓았따.
diaryEditText.addTextChangedListener{
//실행되지 않고 지연되고 있는 runnable이 있다면지워주기 위해 removeCallbacks를 사용.
handler.removeCallbacks(runnable)
handler.postDelayed(runnable,500)
}
}
}
//별도로 쓰레드를 만들게 되면 UI에 관여할수 없다. 따라서 핸들러를 이용하여 작업한다.
val t = Thread(Runnable{
//그래서 나온 방식은 다음과 같다.
runOnUiThread{
MainThread를 열어주는 작업.
}
//혹은
handler.post{
//포스트로 작업을 진행. 핸들러는 메인 루퍼로 만들어서 메인쓰레드와 연결되어있다.
//따라서 post의 람다를 handler에 던져 작업을 진행시키는 방식이다.
}
}
파일안에 Preference라는 파일을 만들어서 데이터를 저장하는 방식
다른 앱과 공유할 수 있다.
sharedpreferences에 데이터를 저장할때는edit이라는 ktx function을 사용하여 저장한다.
저장하는 방식은 commit과 apply가 존재한다.
commit은 UI Thread를 잠시 블락하고 데이터가 저장될때까지 기다리고
apply는 비동기적으로 저장한다.
UI Thread를 block한다는 의미는 이 동작이 끝날때까지 UI Thread가 기다린다는 뜻이다.
//아래와 같이 getSharedPreferences를 이용하여 생성하고 "원하는 이름",Mode를 설정한다.
val passwordPreferences= getSharedPreferences("password", Context.MODE_PRIVATE)
//Preferences를 부를때는 edit()을 열어서 시작하고, putString을 통해 원하는 값을 넣는다.
passwordPreferences.edit(true){
putString("password",passwordFromUser)
}
//저장된 값을 불러올 때에는 getString을 이용한다.
passwordPreferences.getString("password","000")