Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions 23주차/노트
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Service

어플리케이션은 항상 포그라운드에서만 돌아가는게 아니라 백그라운드에서도 수많은 작업이 이루어진다

바로 이 service라는 구성요소로 백그라운드 작업을 수행시킬 수 있다.

서비스는 어플리케이션의 4대 컴포넌트 중 하나로 백그라운드에서 수행할 작업을 직접 설계할 수 있다.

## 서비스의 세 가지 유형

서비스는 세 가지의 유형이 존재한다

### 1.포그라운드

- 포그라운드 서비스는 사용자에게 잘 보이는 몇몇 작업을 수행한다. 예를 들어 오디오 앱이라면 오디오 트랙을 재생할 때 포그라운드 서비스를 사용한다. 포그라운드 서비스는 [알림](https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=ko)을 표시해야 한다. 포그라운드 서비스는 사용자가 앱과 상호 작용하지 않을 때도 계속 실행됩니다.

### 2.백그라운드

- 백그라운드 서비스는 사용자에게 직접 보이지 않는 작업을 수행한다. 예로 어느 앱이 저장소를 압축하는 데에 서비스를 사용했다면 이것은 보통 백그라운드 서비스로 구현된다

### 3.바인드

- 앱의 구성 요소가 `[bindService()](https://developer.android.com/reference/android/content/Context?hl=ko#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int))`를 호출하여 해당 서비스에 바인딩이 되면 서비스가 바인딩 된다 바인딩 된 서비스는 클라이언트-서버 인터페이스를 제공해서 구성 요소가 서비스와 상호 작용하게 되며 결과를 받을 수 있고 또한 이와 같은 작업을 여러 프로세스에 걸쳐 프로세스 간에 통신으로 수행될 수 있다. 바인딩 된 서비스는 또 다른 앱 구성 요소가 이에 바인딩 되어있는 경우에만 실행된다 여러 구성 요소가 서비스에 한꺼번에 바인딩이 될 수 있지만 이 모든 것에서 바인딩이 해제되면 해당 서비스는 소멸된다.

## 서비스의 기본 사항

먼저 서비스를 구현하려면 Service의 하위 클래스를 생성해야한다

구현부에선 서비스의 수명 주기의 주요 사항들을 처리하는 콜백 메서드를 몇가지를 재정의 해야 하며 서비스에 바인딩할 구성 요소에 대한 매커니즘을 제공해야 한다.

### 1. **[onStartCommand()](https://developer.android.com/reference/android/app/Service?hl=ko#onStartCommand(android.content.Intent,%20int,%20int)):**

- 시스템이 이 메서드를 호출하는 경우는 또 다른 구성요소(액티비티 등)가 서비스를 시작하도록 요청하는 경우이며 이때 `[startService()](https://developer.android.com/reference/android/content/Context?hl=ko#startService(android.content.Intent))`를 호출하는 방식으로 서비스를 실행시킨다 이 메서드가 실행되면 서비스가 시작되고 백그라운드에서 무한하게 실행될 수 있으며 작업이 완료되었을 때 해당 서비스를 중단시키면 된다
- 해당 서비스를 중단하는 것은 개발자 본인의 책임이며, 이때 `[stopSelf()](https://developer.android.com/reference/android/app/Service?hl=ko#stopSelf())` 또는 `[stopService()](https://developer.android.com/reference/android/content/Context?hl=ko#stopService(android.content.Intent))`를 호출하면 된다. 한편 바인딩만 제공하고자 하는 경우, 이 메서드를 구현하지 않아도 된다

### 2. **[onBind()](https://developer.android.com/reference/android/app/Service?hl=ko#onBind(android.content.Intent)):**

- 디른 구성 요소가 해당 서비스에 바인딩되고자 하는 경우(예를 들어 RPC를 수행하기 위해)에도 이 메서드를 호출한다. 이때 `[bindService()](https://developer.android.com/reference/android/content/Context?hl=ko#bindService(android.content.Intent,%20android.content.ServiceConnection,%20int))`를 호출하는 방법을 사용한다. 이 메서드를 구현할 때에는 클라이언트가 서비스와 통신을 주고받기 위해 사용할 인터페이스를 제공해야 하며. 이때 `[IBinder](https://developer.android.com/reference/android/os/IBinder?hl=ko)`를 반환하면 된다. 이 메서드는 항상 구현해야 하지만, 바인딩을 허용하지 않으려면 null을 반환해야 한다.

### 3. [onCreate()](https://developer.android.com/reference/android/app/Service?hl=ko#onCreate()):

- onStartComannd() 또는 onBind()에서 서비스를 실행하거나 바인딩을 하고 나면

서비스가 계속해서 실행되고 있는 중이 되기 때문에 일회성으로 실행되며, 서비스가 이미 실행 중이면 onCreate()는 호출되지 않는다.


### **4) [ondestroy()](https://developer.android.com/reference/android/app/Service?hl=ko#onDestroy()):**

- 서비스를 소멸시킬 때 호출한다. 서비스는 스레드, 등록된 리스너 또는 수신기 등의 각종 리소스를 정리하기 위해 이것을 구현해야 한다. 이는 서비스가 수신하는 마지막 호출이다
5 changes: 5 additions & 0 deletions 23주차/소스코드/Constant.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.test.musicplayproject

const val MEDIA_PLAYER_PLAY = "play"
const val MEDIA_PLAYER_PAUSE = "pause"
const val MEDIA_PLAYER_STOP = "stop"
50 changes: 50 additions & 0 deletions 23주차/소스코드/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.test.musicplayproject

import android.content.Intent
import android.media.MediaPlayer
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.test.musicplayproject.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
lateinit var actiivityMainBinding: ActivityMainBinding
var mediaPlayer:MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
actiivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(actiivityMainBinding.root)

actiivityMainBinding.run {
buttonStart.setOnClickListener {
mediaPlayerPlay()
}
buttonStop.setOnClickListener {
mediaPlayerStop()
}
buttonPause.setOnClickListener {
mediaPlayerPause()
}
}
}

fun mediaPlayerPlay(){
val intent = Intent(this@MainActivity,MediaPlayerService::class.java).apply {
action = MEDIA_PLAYER_PLAY
}
startService(intent)


}
fun mediaPlayerStop(){
val intent = Intent(this@MainActivity,MediaPlayerService::class.java).apply {
action = MEDIA_PLAYER_STOP
}
startService(intent)
}
fun mediaPlayerPause(){
val intent = Intent(this@MainActivity,MediaPlayerService::class.java).apply {
action = MEDIA_PLAYER_PAUSE
}
startService(intent)
}
}
34 changes: 34 additions & 0 deletions 23주차/소스코드/MediaPlayerService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.test.musicplayproject

import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.IBinder

class MediaPlayerService : Service() {
var mediaPlayer: MediaPlayer? = null
override fun onBind(intent: Intent): IBinder? {
return null
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when(intent?.action){
MEDIA_PLAYER_PLAY -> {
if (mediaPlayer == null){
mediaPlayer = MediaPlayer.create(baseContext, R.raw.cheer)
}
mediaPlayer?.start()
}
MEDIA_PLAYER_PAUSE -> {
mediaPlayer?.pause()
}
MEDIA_PLAYER_STOP -> {
mediaPlayer?.stop()
mediaPlayer?.release()
mediaPlayer = null
stopSelf()
}
}
return super.onStartCommand(intent, flags, startId)
}
}
17 changes: 17 additions & 0 deletions 23주차/알고리즘/Baek11726.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import java.io.BufferedReader
import java.io.InputStreamReader

fun main(){
val br = BufferedReader(InputStreamReader(System.`in`))

val input = br.readLine().toInt()

val resultArr = LongArray(1000+1){i-> 0}
resultArr[1]=1
resultArr[2]=2

for (i in 3..1000) {
resultArr[i] = (resultArr[i - 1] + resultArr[i - 2]) % 10007
}
print((resultArr[input]))
}
31 changes: 31 additions & 0 deletions 23주차/알고리즘/Baek2775.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import java.io.BufferedReader
import java.io.InputStreamReader

fun main(){
val br = BufferedReader(InputStreamReader(System.`in`))
val inputCount = (br.readLine().toInt())
val problemFloor = IntArray(inputCount){0}
val problemLine = IntArray(inputCount){0}
for (i in 0 until inputCount){
problemFloor[i] = br.readLine().toInt()
problemLine[i] = br.readLine().toInt()
}

//메모리제이션
val resultArr = Array(15){IntArray(15){0}}
for (i in 0..14){
resultArr[0][i] = i
}

//저장
for (k in 1..14){
var countPeopleEachFloor = resultArr[k-1][0]
for (n in 1..14){
resultArr[k][n] = resultArr[k-1][n] + countPeopleEachFloor
countPeopleEachFloor += resultArr[k-1][n]
}
}
for(i in problemFloor.indices){
println(resultArr[problemFloor[i]][problemLine[i]])
}
}
28 changes: 28 additions & 0 deletions 23주차/알고리즘/Beak1003.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import java.io.BufferedReader
import java.io.InputStreamReader

fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val inputCount = br.readLine().toInt()
val inputArr = IntArray(inputCount) { i ->
br.readLine().toInt()
}

val resultArr = Array(41){i->LongArray(2){i->0} }

resultArr[0][0] = 1
resultArr[0][1] = 0
resultArr[1][0] = 0
resultArr[1][1] = 1
resultArr[2][0] = 1
resultArr[2][1] = 1

for (index in 3..40){
resultArr.get(index)[0] = resultArr.get(index-1)[0] + resultArr.get(index-2)[0]
resultArr.get(index)[1] = resultArr.get(index-1)[1] + resultArr.get(index-2)[1]
}

for (index in inputArr){
println("${resultArr.get(index)[0]} ${resultArr.get(index)[1]}")
}
}
Binary file added 23주차/코딩예제/1212_musicPlayer.zip.zip
Binary file not shown.