Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature/WEEK 2] WEEK2 part2 #10

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

[feature/WEEK 2] WEEK2 part2 #10

wants to merge 2 commits into from

Conversation

sery270
Copy link
Member

@sery270 sery270 commented Oct 10, 2021

  • 메인 스레드와 Handler Part 2 - 안드로이드 애플리케이션에서의 메인 스레드

  • WEEK 3의 내용인 2.5장(invalidate())은 생략하였습니다.

  • 아래와 같은 이유로 2.6장(ANR)을 생략하고 초고를 작성하였습니다.

    • WEEK2에서 전달하고자 하는 내용이 너무 광범위해져 아티클의 방향이 모호해진다고 판단하였습니다.
    • ANR에 대해선 간단히 언급하는 것이 아니라 WEEK를 투자하여 다뤄도 좋을만한 주제라 생각하였습니다.

Copy link
Member

@l2hyunwoo l2hyunwoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다.


백그라운드 스레드가 (UI와 관련하여 단일 스레드 모델이 적용된다는 점에서) 여러 특권을 가진 메인스레드에게 일을 분담하기 위해, 기본적으로 사용되는 구조가 되는 것입니다. 이번 아티클에서는 과연 그 '특권'이란 무엇이고 왜 생겨났는지, 어떻게 사용되어야하는지에 대해 알고자 합니다. 안드로이드 프레임 워크의 관점에서, 메인 스레드의 의미와 역할에 대해 알아보겠습니다.
이는 여러 스레드를 사용하는 멀티스레드 환경에서, 특정 스레드에게 일을 위임하기 위한 수단으로 의미가 있습니다. 백그라운드 스레드가 특권을 가진 메인스레드에게 일을 분담하기 위해, 기본적으로 사용되는 구조가 되는 것입니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
이는 여러 스레드를 사용하는 멀티스레드 환경에서, 특정 스레드에게 일을 위임하기 위한 수단으로 의미가 있습니다. 백그라운드 스레드가 특권을 가진 메인스레드에게 일을 분담하기 위해, 기본적으로 사용되는 구조가 되는 것입니다.
이는 멀티스레드 환경에서, 특정 스레드에게 일을 위임하기 위한 수단으로 의미가 있습니다. 백그라운드 스레드가 **'특권'** 가진 메인스레드에게 일을 분담하기 위해, 기본적으로 사용되는 구조가 되는 것입니다.
  • 단어 중복을 최대한 자제해주시면 감사링
  • 따옴표를 빼면 특권이라는 단어 자체가 일반적인 의미를 가지기 때문에 여기서는 다른 의미를 주었다는 텐스를 주기 위해서 강조점을 주는게 좋을 것 같음

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일을 분담한다는건 백그라운드 스레드가 그 일에 주도권을 가지고 있었는데 그걸 메인스레드에게 넘긴다라는 뜻도 내포되어있는 것 같습니다(뉘앙스). 메인스레드와 협업을 한다는 표현이 좀 더 적절할 수 있겠네요. 결국에는 스레드도 객체니까요.


UI 처리를 위한 메인 스레드
이번 아티클에서는 과연 그 '특권'이란 무엇이고 왜 생겨났는지, 어떻게 사용되어야하는지에 대해 알고자 합니다. 안드로이드 프레임 워크의 관점에서의 메인 스레드의 의미와 역할에 대해 알아보겠습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
이번 아티클에서는 과연 그 '특권'이란 무엇이고 왜 생겨났는지, 어떻게 사용되어야하는지에 대해 알고자 합니다. 안드로이드 프레임 워크의 관점에서의 메인 스레드의 의미와 역할에 대해 알아보겠습니다.
이번 아티클에서는 과연 그 '특권'이란 무엇이고 왜 생겨났는지, 어떻게 사용되어야하는지에 대해 알고자 합니다. 안드로이드 프레임워크의 관점에서의 메인 스레드의 의미와 역할에 대해 알아보겠습니다.

Framework, not Frame Work

Comment on lines +19 to +36
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

// Install selective syscall interception
AndroidOs.install();

// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);

Environment.initForCurrentUser();

// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);

// Call per-process mainline module initialization.
initializeMainlineModules();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 이 아티클과 관련이 덜한 부분이기 때문에 지우면 감사하겠습니다. (보여주고자 하는 부분만 제대로 보여주자는 의미)


- 단일 스레드에서의 긴 작업은 어플리케이션의 반응성을 낮추거나, ANR의 원인이 될 수 있습니다. 따라서 메인 스레드에선 정해진 최소한의 일만 담당하고, 특히 긴 작업은 다른 스레드가 담당하게 해야합니다.
- 따라서 이 메인 스레드와 다른 스레드가 협업하기위해, **스레드간 통신**이 필요하게 되었습니다.
- 안드로이드에선 **Looper와 Handler를 사용하여, 다른 스레드와 메인 스레드간의 통신**을 할 수 있습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 다른 스레드와 메인 스레드간 통신만 가능하다는 오해를 불러일으킬 수 있을 것 같네요(물론 그건 읽는 사람이 잘못한거지만)
우리는 친절한 시바놈이니까 스레드간의 통신을 사용할 때 Handler와 Looper를 사용하기에 메인스레드와 다른 스레드 간에 통신을 할 때에도 핸들러 루퍼구조를 활용한다 정도로 바꿔도 좋을 것 같습니다.

@jinsu4755 @SSong-develop @kym1924 이에대한 의견 부탁드립니다.


### 반복 UI 갱신를 위한 recursive Runnable

- 시계나 타이머처럼 반복적으로 UI 작업을 해야할 때가 있습니다. 이 UI 갱신 작업은 Runnable을 재귀적으로 설계하는 것으로 구현할 수 있습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

구현화면 부착하면 더 좋을 듯?

Comment on lines +113 to +133
class MainActivity : AppCompatActivity() {
private val DELAY_TIME = 2000L
private val handler = Handler(mainLooper)
private var updateTimeRunnable: Runnable? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
updateTimeRunnable = Runnable {
findViewById<TextView>(R.id.tv1).text = System.currentTimeMillis().toString()
updateTimeRunnable?.let { handler.postDelayed(it, DELAY_TIME) }
}

}


fun onClickButton(view: TextView){
updateTimeRunnable?.let { handler.post(it) }
}

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good!

Comment on lines +139 to +141
### 타이머, ANR 판단

-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### 타이머, ANR 판단
-

delete plz

@@ -0,0 +1,190 @@
# 백그라운드 스레드 part1 - HandlerThread 클래스

오늘은 백그라운드 스레드를 구현하는데 많이 사용되는 [HandlerThread](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=40?q=handlert&sq=&hl=ko) 이 클래스에 대해 알아보면서, 지난 글에서 다뤄보았던 [Handler와 Looper 그리고 MessageQueue의 동작 방식](https://medium.com/write-android/%EB%A9%94%EC%9D%B8-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-handler-part-1-handler%EC%99%80-looper-%EA%B7%B8%EB%A6%AC%EA%B3%A0-messagequeue%EC%9D%98-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-f0bee443d71e) 에 대한 이해를 심화시켜보는 시간을 가져보려고 합니다. HandlerThread의 멤버에 대해 이해하고, HandlerThread가 필요한 이유를 이해해보도록 하겠습니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
오늘은 백그라운드 스레드를 구현하는데 많이 사용되는 [HandlerThread](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=40?q=handlert&sq=&hl=ko) 클래스에 대해 알아보면서, 지난 글에서 다뤄보았던 [Handler와 Looper 그리고 MessageQueue의 동작 방식](https://medium.com/write-android/%EB%A9%94%EC%9D%B8-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-handler-part-1-handler%EC%99%80-looper-%EA%B7%B8%EB%A6%AC%EA%B3%A0-messagequeue%EC%9D%98-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-f0bee443d71e) 에 대한 이해를 심화시켜보는 시간을 가져보려고 합니다. HandlerThread의 멤버에 대해 이해하고, HandlerThread가 필요한 이유를 이해해보도록 하겠습니다.
이 글에서는 백그라운드 스레드를 구현하는데 많이 사용되는 [HandlerThread](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=40?q=handlert&sq=&hl=ko) 클래스에 대해 알아보면서 HandlerThread가 왜 구현되었는 지를 이해하고, 지난 글 ([Handler와 Looper 그리고 MessageQueue의 동작 방식](https://medium.com/write-android/%EB%A9%94%EC%9D%B8-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-handler-part-1-handler%EC%99%80-looper-%EA%B7%B8%EB%A6%AC%EA%B3%A0-messagequeue%EC%9D%98-%EB%8F%99%EC%9E%91-%EB%B0%A9%EC%8B%9D-f0bee443d71e))을 심화해서 이해해보고자 합니다.

말이 풀어써져 있어서 응집시켜봤습니다.

Comment on lines +11 to +13
## HandlerThread의 멤버

### HandlerThread 클래스
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## HandlerThread의 멤버
### HandlerThread 클래스
## class HandlerThread

계층이 너무 나눠져 있어서 조금 통합해야할 것 같습니다.

Comment on lines +23 to +46
### 필드

### [`mPriority`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=29?hl=ko)

> The priority to run the thread at.

- 스레드를 실행할 우선 순위입니다.

### [`mTid`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=30?hl=ko)

- 현재 스레드의 아이디입니다.
- -1이 디폴트 값으로 설정되어있습니다.
- `run()` 내부에서 `Process.myTid()` 로 초기화됩니다.
- `loop()` 함수 종료 후 -1로 초기화됩니다.

### [`mLooper`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=31?hl=ko)

- 현재 스레드와 연결된 루퍼입니다.
- HandlerThread의 `run()`에서 자동적으로 연결됩니다.

### [`mHandler`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=32?hl=ko)

- 현재 스레드의 루퍼와 연결된 핸들러입니다.
- `mLooper`와는 달리, 개발자가 직접 연결해주어야하는 부분입니다.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### 필드
### [`mPriority`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=29?hl=ko)
> The priority to run the thread at.
- 스레드를 실행할 우선 순위입니다.
### [`mTid`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=30?hl=ko)
- 현재 스레드의 아이디입니다.
- -1이 디폴트 값으로 설정되어있습니다.
- `run()` 내부에서 `Process.myTid()` 로 초기화됩니다.
- `loop()` 함수 종료 후 -1로 초기화됩니다.
### [`mLooper`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=31?hl=ko)
- 현재 스레드와 연결된 루퍼입니다.
- HandlerThread의 `run()`에서 자동적으로 연결됩니다.
### [`mHandler`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=32?hl=ko)
- 현재 스레드의 루퍼와 연결된 핸들러입니다.
- `mLooper`와는 달리, 개발자가 직접 연결해주어야하는 부분입니다.
### 필드
#### [`mPriority`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=29?hl=ko)
> The priority to run the thread at.
- 스레드를 실행할 우선 순위입니다.
#### [`mTid`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=30?hl=ko)
- 현재 스레드의 아이디입니다.
- -1이 디폴트 값으로 설정되어있습니다.
- `run()` 내부에서 `Process.myTid()` 로 초기화됩니다.
- `loop()` 함수 종료 후 -1로 초기화됩니다.
#### [`mLooper`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=31?hl=ko)
- 현재 스레드와 연결된 루퍼입니다.
- HandlerThread의 `run()`에서 자동적으로 연결됩니다.
#### [`mHandler`](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/os/HandlerThread.java;l=32?hl=ko)
- 현재 스레드의 루퍼와 연결된 핸들러입니다.
- `mLooper`와는 달리, 개발자가 직접 연결해주어야하는 부분입니다.

아래에 있는 필드들은 제목 '필드'의 하위 계층이 되어야 하는데 그런 처리가 안되어 있습니다. 이는 하단에도 해당되는 것 같으니 수정부탁드립니다.

Copy link

@kym1924 kym1924 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kym1924 kym1924 self-requested a review October 24, 2021 11:11
Copy link

@kym1924 kym1924 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants