Androidμ 4λ μ»΄ν¬λνΈ μ€ νλμΈ Serviceλ UI μμ΄ λ°±κ·ΈλΌμ΄λμμ μ€νλλ©° μ₯μκ° μμ μ μννλ ν΅μ¬ μμμ λλ€.
μμ μ¬μ, λ€νΈμν¬ μμ , GPS λ± μ¬μ©μμ μ§μ μνΈμμ©νμ§ μλ μμ μ μνν©λλ€.
μ΄ κ°μ΄λμμλ Serviceμ κ°λ , μ€ν λ°©μ, μ΅μ λ²μ μ μ μ½μ¬νκΉμ§ μμ보λλ‘ νκ² μ΅λλ€.
Service
UI μμ΄ Backgroundμμ μ€νλλ μ»΄ν¬λνΈλ‘, μ±μ μ€ν μ¬λΆμ κ΄κ³μμ΄ μ₯μκ° μνν΄μΌ νλ μμ μ μ²λ¦¬νλλ° μ¬μ©λ©λλ€.
Serviceλ μ±μ΄ μ¬μ©μμ μ§μ μνΈμμ©νμ§ μμλ μ€νλλ©°, λ€λ₯Έ μ»΄ν¬λνΈ(Activity, Broadcast Receiver λ±)μ μνΈμμ©ν μ μμ΅λλ€.
Serviceλ λ€μκ³Ό κ°μ΄ 2κ°λ‘ λλ μ μμ΅λλ€.
- ν¬κ·ΈλΌμ΄λ μλΉμ€(Foreground Service)
- μλ¦Ό(Notification)κ³Ό ν©κ³ λ°±κ·ΈλΌμ΄λμμ μ€ν
- μ) μμ νλ μ΄μ΄, λ€λΉκ²μ΄μ λ±
- λ°±κ·ΈλΌμ΄λ μλΉμ€(Background Service)
- UI μμ΄ λ°±κ·ΈλΌμ΄λμμ μ€ν
- Android 8.0(API 26) μ΄μμμλ μ€νμ μ ν
- μ) λ°μ΄ν° λκΈ°ν, λ€νΈμν¬ μμ² λ±
κ·Έλ¦¬κ³ κ΅¬ν λ°©μμ μ°¨μ΄κ° μλ BoundServiceκ° μμ΅λλ€.
μμλλ‘ νλμ© μμλ³΄κ² μ΅λλ€.
Foreground Service
Foreground Serviceλ μ¬μ©μκ° νμ¬ μ€ν μ€μμ μΈμ§ν μ μλλ‘ μλ¦Ό(Notification)μ νμνλ©΄μ λμνλ μλΉμ€μ λλ€.
λ³΄ν΅ μ€λ μ€νλκ±°λ μ€μν μμ (μμ μ¬μ, GPS λ±)μ μνν λ μ¬μ©λλ©°, μμ€ν μ λ©λͺ¨λ¦¬κ° λΆμ‘±ν΄λ μ½κ² μ’ λ£λμ§ μμ΅λλ€.
λ€μμ κ°λ¨ν Foreground Service ꡬν μμμ λλ€.
class MyForegroundService: Service() {
override fun onCreate() {
super.onCreate()
startForeground(1, createNotification()) // Foreground μνλ‘ λ³κ²½
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// μ€νν μμ
μν
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
stopForeground(true) // Foreground Service μ’
λ£
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
private fun createNotification(): Notification {
val channelId = "foreground_service_channel"
val channelName = "Foreground Service Channel"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId, channelName, NotificationManager.IMPORTANCE_LOW
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
}
return NotificationCompat.Builder(this, channelId)
.setContentTitle("Foreground Service")
.setSmallIcon(R.drawable.ic_service_icon)
.build()
}
}
AndroidManifest.xml λ΄μ μλΉμ€λ₯Ό μ μΈν΄μΌ μ¬μ©ν μ μμ΅λλ€.
<manifest>
<application>
<service android:name=".MyForegroundService" />
</application>
</manifest>
μλΉμ€λ₯Ό μ€ννκ³ μ νλ μμΉμμ Intentλ₯Ό μ¬μ©ν΄ Foreground Serviceλ₯Ό μ€νν©λλ€.
val serviceIntent = Intent(context, MyForegroundService::class.java)
startForegroundService(serviceIntent)
Foreground Serviceλ₯Ό μ€νν λλ λ°λμ startForeground() λ©μλλ₯Ό νΈμΆν΄μΌ ν©λλ€.
μμ€ν μ΄ μλΉμ€ μ’ λ£λ₯Ό λ°©μ§νκ³ , κ°μ μ’ λ£λ κ°λ₯μ±μ μ€μ¬μ€λλ€.
μ°Έκ³ λ‘ μ΄ λ©μλλ₯Ό νΈμΆνμ§ μμΌλ©΄ Android 8.0(API 26) μ΄μμ νκ²½μμλ μλΉμ€κ° μ€νλμ§ μμ΅λλ€.
startForeground(NOTIFICATION_ID, createNotification())
λν, Android 8.0λΆν° μλΉμ€μμ μλ¦Όμ λμ°κΈ° μν΄ Notification Channelμ μ€μ ν΄μΌ ν©λλ€.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"foreground_service_channel",
"Foreground Service Channel",
NotificationManager.IMPORTANCE_LOW
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(channel)
}
μλΉμ€λ₯Ό μ’ λ£ν λλ μλμ κ°μ΅λλ€.
첫 λ²μ§Έλ‘ μλΉμ€ λ΄μμ μλ ν¨μλ₯Ό νΈμΆνκ±°λ,
stopSelf()
λ λ²μ§Έλ‘ μΈλΆμμ Intentλ₯Ό μ¬μ©ν΄ μ’ λ£ν©λλ€.
val serviceIntent = Intent(context, MyForegroundService::class.java)
stopService(serviceIntent)
Android λ²μ μ λ°λ₯Έ λ³κ²½ μ¬ν
Android 13 μ΄νλ‘ 2κ°μ§μ μ νμ΄ μΆκ°λμ΄, Android 14λΆν° Foreground Serviceλ₯Ό 8κ°μ§ μ νμΌλ‘ λΆλ₯ν΄μΌ ν©λλ€.
μ΄μ μ±μ΄ Foreground Serviceλ₯Ό μμν λ μ μ ν μ νμ μ μΈν΄μΌ νλ©°, λΆμ μ ν μ νμ μ¬μ©νλ©΄ μ€νμ΄ μ νλ©λλ€.
Foreground Service μ ν | μ€λͺ |
mediaPlayback | μμ , λμμ λ±μ λ―Έλμ΄ μ¬μμ μν μλΉμ€ |
mediaProjection | νλ©΄ λ Ήν, μΊ‘μ²λ₯Ό μν μλΉμ€ |
phoneCall | μ ν λ° VolP ν΅νλ₯Ό μν μλΉμ€ |
location | GPSμ κ°μ μμΉ κΈ°λ° μλΉμ€ |
connectedDevice | λΈλ£¨ν¬μ€, USB λ±μ κΈ°κΈ°μ μ°κ²°λ μλΉμ€ |
health | νΌνΈλμ€ λ° κ±΄κ° κ΄λ ¨ μλΉμ€ |
remoteMessaging | νΈμ μλ¦Όμ ν¬ν¨ν μ격 λ©μμ§ μλΉμ€ |
systemExempted | μμ€ν μμ νΉλ³ν νμ©νλ μλΉμ€ (μΌλ° μ±μμ μ¬μ© λΆκ°) |
μλμ κ°μ΄ AndroidManifest.xmlμ Foreground Service μ νμ μ μΈν΄μΌ ν©λλ€.
<manifest>
<application>
<service
android:name=".MyForegroundService"
android:foregroundServiceType="mediaPlayback"/>
</application>
</manifest>
κ·Έλ¦¬κ³ μ μΈν μ νμ λ§λ κΆνμ μΆκ°ν΄μΌ ν©λλ€.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
Background Service
Background Serviceλ μ¬μ©μκ° μ§μ μΈν°νμ΄μ€μ μνΈμμ©νμ§ μλ μνμμ μ€νλλ μλΉμ€λ₯Ό μλ―Έν©λλ€. μ¦, νλ©΄μ UIλ₯Ό λμ°μ§ μκ³ λ°±κ·ΈλΌμ΄λμμ μ‘°μ©ν λμνλ μλΉμ€μ λλ€. Foreground Serviceμ λ¬λ¦¬, μλ¦Όμ λ°λ‘ νμνμ§ μμλ λ©λλ€.
νμ§λ§ Android 8.0 μ΄μλΆν° κ°λ ₯ν μ νμ΄ λ°λ₯΄λ©°, Android 13-14λΆν°λ Foreground Serviceμ μ ν λΆλ₯κΉμ§ λμ λλ©° λμ± μ¬μ©μ΄ μ΄λ €μμ‘μ΅λλ€.
λ€μμ κ°λ¨ν Background Service μμμ λλ€.
class MyBackgroundService: Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) {
Thread {
for (i in 1..10) {
Log.d("Background Service", "Running: $i")
Thread.sleep(1000)
}
stopSelf()
}.start()
return START_STICKY
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
<manifest>
<application>
<service android:name=".MyBackgroundService" />
</application>
</manifest>
val serviceIntent = Intent(this, MyBackgroundService::class.java)
startService(serviceIntent)
Background Service μ€ν μ ν
μμμ μΈκΈνλ€μνΌ, Android 8.0 μ΄μλΆν° λ°±κ·ΈλΌμ΄λ μ€νμ΄ μ νλ©λλ€. μ¦, μ±μ΄ λ°±κ·ΈλΌμ΄λμ μμΌλ©΄ startService() ν¨μ νΈμΆμ΄ μ€ν¨νκ³ , λͺ μ΄ λ΄μ μλμΌλ‘ μ’ λ£λ©λλ€.
λ°λΌμ Background Serviceμ λμμΌλ‘, μλ λ κ°μ§ λ°©λ²μ΄ μμ΅λλ€.
- Foreground Serviceλ‘ λ체νκΈ°
- WorkManager μ¬μ©νκΈ°
μμμ Foreground Serviceμ λν΄ μμ보μμΌλ, WorkManagerμ λν΄μλ§ κ°λ΅ν μ€λͺ νκ² μ΅λλ€.
WorkManager
WorkManagerλ λ°±κ·ΈλΌμ΄λ μμ μ μμ νκ³ ν¨μ¨μ μΌλ‘ μ€ννκΈ° μν Jetpack λΌμ΄λΈλ¬λ¦¬μ λλ€.
μ±μ΄ μ’ λ£λκ±°λ κΈ°κΈ°κ° μ¬λΆν λμ΄λ μμ μ μ μ§ν μ μκ³ , λ€νΈμν¬λ λ°°ν°λ¦¬ μν λ±μ κ³ λ €νμ¬ μμ μ μ€νν μ μμ΅λλ€.
class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
// λ°±κ·ΈλΌμ΄λμμ μ€νν μμ
return Result.success()
}
}
// Work μμ² μμ± λ° μ€ν
val workRequest = OneTimeWorkRequestBuilder<MyWorker>().build()
WorkManager.getInstance(context).enqueue(workRequest)
μμ μ ν λ² λλ, μ£ΌκΈ°μ μΌλ‘ μννλλ‘ μ€μ ν μ μμ΅λλ€.
μ€μ λ‘ Foreground Serviceλ₯Ό ν΅ν΄ μμλ‘ μ»μ μ¬μ©μ λ°μ΄ν°λ₯Ό ν루μ ν λ² μλ²μ μ μ₯ν λ WorkManagerλ₯Ό μ¬μ©νμ΅λλ€. μ€ν κ°κ²©μ 12μκ°μΌλ‘ λκΈ΄ νλλ°, μ€μ λ‘λ λ λΉ λ₯΄κ±°λ λλ €μ§λ κ²½μ°κ° μμμ΅λλ€.
μ νν μ€μ ν μ£ΌκΈ°λλ‘ λμνμ§λ μκ³ , μ΄λ μ λμ μ€μ°¨λ μμ΅λλ€.
Bound Service
Bound Serviceλ ν΄λΌμ΄μΈνΈ(Activity, Fragment λ±)κ° λ°μΈλ©(Binding)νμ¬ μ§μ μνΈμμ©ν μ μλ μλΉμ€μ λλ€. μ¦, ν΄λΌμ΄μΈνΈμ μλ²κ° μ°κ²°λ ννλ‘ λμνλ μλΉμ€μ λλ€.
Bound Serviceλ ν΄λΌμ΄μΈνΈμ μλ²(μλΉμ€) κ°μ μλ°©ν₯ ν΅μ μ΄ κ°λ₯νλ©°, ν΄λΌμ΄μΈνΈκ° λ°μΈλ©μ ν΄μ νλ©΄ μλΉμ€κ° μλμΌλ‘ μ’ λ£λ©λλ€. Messager, AIDL, Binder λ±μ λ©μ»€λμ¦μ μ¬μ©νμ¬ λ°μ΄ν°λ₯Ό κ΅νν μ μμ΅λλ€.
Bound Service κΈ°λ³Έμ μΈ λμμ λ€μκ³Ό κ°μ΅λλ€.
- ν΄λΌμ΄μΈνΈκ° bindService()λ₯Ό νΈμΆνμ¬ μλΉμ€μ λ°μΈλ©
- μλΉμ€λ onBind()λ₯Ό ꡬννμ¬ IBinder κ°μ²΄λ₯Ό λ°ν
- ν΄λΌμ΄μΈνΈλ IBinderλ₯Ό ν΅ν΄ μλΉμ€μ λ©μλλ₯Ό νΈμΆ
- ν΄λΌμ΄μΈνΈκ° unbindService()λ₯Ό νΈμΆνκ±°λ μλ©Έλλ©΄ μλΉμ€λ μ’ λ£
Bound Serviceλ₯Ό ꡬννλ μ¬λ¬ κ°μ§ λ°©λ²μ νλμ© μ΄ν΄λ³΄κ² μ΅λλ€.
LocalBinder
ν΄λΌμ΄μΈνΈμ μλΉμ€κ° κ°μ νλ‘μΈμ€μμ μ€νλ λ μ¬μ©νλ κ°μ₯ κ°λ¨ν λ°©λ²μ λλ€.
μλΉμ€μμ Binder κ°μ²΄λ₯Ό λ°ννλ©΄, ν΄λΌμ΄μΈνΈλ μ΄λ₯Ό μ΄μ©ν΄ μλΉμ€μ λ©μλλ₯Ό μ§μ νΈμΆν μ μμ΅λλ€.
μ§μ λ©μλλ₯Ό νΈμΆνκΈ° λλ¬Έμ μ±λ₯μ΄ μ’κ³ μ¬λ¬ κ°μ ν΄λΌμ΄μΈνΈλ₯Ό λμμ μ°κ²°ν μ μμ΅λλ€.
νμ§λ§ λ€λ₯Έ νλ‘μΈμ€μμλ μ¬μ©ν μ μμ΅λλ€.
κΈ°λ³Έμ μΈ λμμ λ€μκ³Ό κ°μ΅λλ€.
- μλΉμ€μμ Binder κ°μ²΄λ₯Ό μμ±νκ³ λ°ν
- ν΄λΌμ΄μΈνΈκ° bindService()λ₯Ό νΈμΆνλ©΄, onBind()μμ Binderλ₯Ό λ°ν
- ν΄λΌμ΄μΈνΈλ Binderλ₯Ό μ΄μ©ν΄ μλΉμ€μ λ©μλλ₯Ό μ§μ νΈμΆ
λ€μμ LocalBinderλ₯Ό μ¬μ©νμ¬ κ΅¬νν μ½λμ λλ€.
class MyLocalService : Service() {
private val binder = LocalBinder()
inner class LocalBinder : Binder() {
fun getService(): MyBoundService = this@MyLocalService
}
override fun onBind(intent: Intent?): IBinder {
return binder
}
fun getData(): String {
return "Hello from Bound Service!"
}
}
class MainActivity : AppCompatActivity() {
private var service: MyLocalService? = null
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
val localBinder = binder as MyLocalService.LocalBinder
service = localBinder.getService()
isBound = true
}
override fun onServiceDisconnected(name: ComponentName?) {
isBound = false
}
}
override fun onStart() {
super.onStart()
val intent = Intent(this, MyLocalService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
override fun onStop() {
super.onStop()
if (isBound) {
unbindService(connection)
isBound = false
}
}
}
μ¬κΈ°μ MyBoundServiceκ° μλ², MainActivityκ° ν΄λΌμ΄μΈνΈμ μν μ λλ€.
μ 리νμλ©΄, Local Binderλ κ°μ μ± λ΄μμ μλΉμ€μ λ©μλλ₯Ό μ§μ νΈμΆν λ, νλ‘μΈμ€ κ° ν΅μ (IPC)μ΄ νμ μμ λ μ¬μ©ν©λλ€.
μλ₯Ό λ€μ΄ μμ νλ μ΄μ΄ μ±μμ νμ¬ μ¬μ μ€μΈ 곑μ μ 보λ₯Ό κ°μ Έμ€κ±°λ, νΌνΈλμ€ μ±μμ μ€μκ° μΌμ λ°μ΄ν°λ₯Ό κ°μ Έμ€λ κ²½μ°μ μ¬μ©ν μ μμ΅λλ€.
Messenger
IPC(Inter-Process-Communication)λ₯Ό μ§μνλ λ°©μμ λλ€. νΈλ€λ¬λ₯Ό μ΄μ©νμ¬ μλΉμ€μ ν΄λΌμ΄μΈνΈ κ°μ λ©μμ§λ₯Ό μ£Όκ³ λ°μΌλ©° λΉλκΈ° μ²λ¦¬κ° κ°λ₯ν©λλ€. λ°λΌμ Messengerλ λΉλκΈ° λ©μμ§ λ°©μμ΄κΈ° λλ¬Έμ μ§μ λ©μλλ₯Ό νΈμΆν μ μμ΅λλ€.
μ΄ λ°©μμ ν΄λΌμ΄μΈνΈκ° μλΉμ€μ μ§μ μ κ·Όν νμ μμ΄ μμ²μ λ©μμ§ ννλ‘ μ λ¬νλ λ°©μμ λλ€. λ°λΌμ λ°μ΄ν°λ₯Ό Message κ°μ²΄λ‘ μ λ¬ν΄μΌ νλ©°, λμ©λ λ°μ΄ν° μ²λ¦¬μλ μ ν©νμ§ μμ΅λλ€.
κΈ°λ³Έμ μΈ λμμ λ€μκ³Ό κ°μ΅λλ€.
- μλΉμ€λ Handlerλ₯Ό μμ±νμ¬ Messengerλ₯Ό ν΅ν΄ ν΄λΌμ΄μΈνΈμ λ©μμ§λ₯Ό μ²λ¦¬
- ν΄λΌμ΄μΈνΈλ Messenger κ°μ²΄λ₯Ό μ¬μ©νμ¬ λ©μμ§λ₯Ό μ μ‘
- μλΉμ€λ λ©μμ§λ₯Ό λ°κ³ νμν μμ μ μνν ν μλ΅μ λ³΄λΌ μ μμ
λ€μμ Messengerλ₯Ό μ¬μ©νμ¬ κ΅¬νν μ½λμ λλ€.
class MyMessengerService : Service() {
private val messenger = Messenger(IncomingHandler())
inner class IncomingHandler : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
1 -> Log.d("MessengerService", "Received Message from Client")
else -> super.handleMessage(msg)
}
}
}
override fun onBind(intent: Intent?): IBinder {
return messenger.binder
}
}
class ClientActivity : AppCompatActivity() {
private var messenger: Messenger? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
messenger = Messenger(service)
val message = Message.obtain(null, 1)
messenger?.send(message)
}
override fun onServiceDisconnected(name: ComponentName?) {
messenger = null
}
}
override fun onStart() {
super.onStart()
Intent(this, MyMessengerService::class.java).also { intent ->
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}
override fun onStop() {
super.onStop()
unbindService(connection)
}
}
Messengerλ μ¬λ¬ ν΄λΌμ΄μΈνΈκ° νλμ μλΉμ€μ ν΅μ ν΄μΌ νμ§λ§, ν λ²μ νλμ μμ²λ§ μ²λ¦¬νλ©΄ λλ κ²½μ°μ μ¬μ©ν©λλ€.
λν νλ‘μΈμ€ κ° ν΅μ (IPC)μ΄ νμνμ§λ§ λ¨μν λ©μμ§ μ λ¬μ΄ μ£Όλͺ©μ μΌ λ, κ·Έλ¦¬κ³ μλΉμ€κ° μ¬λ¬ ν΄λΌμ΄μΈνΈμ μ°κ²°λμ§λ§ μμ²μ μμ°¨μ μΌλ‘ μ²λ¦¬ν λ μ¬μ©ν©λλ€.
μλ₯Ό λ€μλ©΄, νμΌ λ€μ΄λ‘λ μνλ₯Ό UIμ Notificationμ λμμ μ λ¬νκ±°λ, κ²μ μ±μμ λ°±κ·ΈλΌμ΄λ μλΉμ€κ° μλ²μμ λ°μ΄ν°λ₯Ό λ°μμ UIλ₯Ό μ λ°μ΄νΈνλ κ²½μ°μ μ¬μ©λ μ μμ΅λλ€.
AIDL(Android Interface Definition Language)
AIDLμ λ€λ₯Έ νλ‘μΈμ€μμλ μλΉμ€μ λ©μλλ₯Ό μ§μ νΈμΆν μ μλλ‘ μ§μνλ IPC λ°©μμ λλ€.
Messagengerλ³΄λ€ λ κ°λ ₯ν κΈ°λ₯μ μ 곡νλ©°, λ€μ€ ν΄λΌμ΄μΈνΈκ° λμμ μμ²μ λ³΄λΌ μ μμ΅λλ€. νμ§λ§ μ€μ μ΄ λ³΅μ‘νκ³ , κ°λ° λΉμ©μ΄ λλ€λ λ¨μ μ΄ μμ΅λλ€.
κΈ°λ³Έμ μΈ λμμ λ€μκ³Ό κ°μ΅λλ€.
- AIDL νμΌμ μμ±νμ¬ μΈν°νμ΄μ€ μ μ (.aidl νμΌ)
- μ»΄νμΌλ¬κ° μλμΌλ‘ Stub ν΄λμ€λ₯Ό μμ±
- ν΄λΌμ΄μΈνΈλ binderService()λ₯Ό ν΅ν΄ μλΉμ€μ λ°μΈλ©
- ν΄λΌμ΄μΈνΈλ Stub κ°μ²΄λ₯Ό μ¬μ©νμ¬ μ격 λ©μλλ₯Ό μ§μ νΈμΆ
λ€μμ AIDLλ₯Ό μ¬μ©νμ¬ κ΅¬νν μ½λμ λλ€.
AIDLμ μμ LocalBinder, Messengerμ λ¬λ¦¬ .aidl νμΌμ μμ±ν΄μΌ ν©λλ€.
package com.example.aidl;
interface MyAidlInterface {
String getMessage();
}
class MyAidlService : Service() {
private val binder = object : MyAidlInterface.Stub() {
override fun getMessage(): String {
return "Hello from AIDL Service!"
}
}
override fun onBind(intent: Intent?): IBinder {
return binder
}
}
class ClientActivity : AppCompatActivity() {
private var myService: MyAidlInterface? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
myService = MyAidlInterface.Stub.asInterface(service)
Log.d("AIDLService", "Message: ${myService?.getMessage()}")
}
override fun onServiceDisconnected(name: ComponentName?) {
myService = null
}
}
override fun onStart() {
super.onStart()
Intent(this, MyAidlService::class.java).also { intent ->
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}
override fun onStop() {
super.onStop()
unbindService(connection)
}
}
μ 리νμλ©΄ AIDLμ λ©ν° νλ‘μΈμ€ νκ²½μμ ν΄λΌμ΄μΈνΈκ° μ격 λ©μλλ₯Ό νΈμΆνκ³ , 볡μ‘ν λ°μ΄ν°(κ°μ²΄, 리μ€νΈ λ±)λ₯Ό μ²λ¦¬ν λ μ¬μ©ν©λλ€. λ³λ ¬λ‘ μ²λ¦¬ν΄μΌ νλ μμ²μ΄ μκ±°λ, μ¬λ¬ ν΄λΌμ΄μΈνΈκ° λμμ μμ²μ 보λ΄κ³ μλ΅μ λ°μμΌ νλ κ²½μ°μλ μ¬μ©ν μ μμ΅λλ€.
μλ₯Ό λ€λ©΄ λ―Έλμ΄ νλ μ΄μ΄ μ±μ΄ Android System Media Session Serviceμ ν΅μ νκ±°λ, VPN μλΉμ€μμ λ€νΈμν¬ νΈλν½μ μ μ΄νλ κ²½μ°μ μ¬μ©ν μ μμ΅λλ€.
μ§κΈκΉμ§ μλΉμ€μ λν κ°λ κ³Ό λμ λ°©μ, λ€μν μ νμ λν΄ μ΄ν΄λ³΄μμ΅λλ€. μλλ‘μ΄λμμ μλΉμ€λ λ°±κ·ΈλΌμ΄λ μμ μ μννλ ν΅μ¬μ μΈ μ»΄ν¬λνΈμ΄μ§λ§, λ°°ν°λ¦¬ μ΅μ ν λ° μ¬μ©μ κ²½νμ κ³ λ €ν΄μΌ νλ―λ‘ μ¬μ©μ μ£Όμκ° νμν©λλ€.
νΉν μ΅μ μλλ‘μ΄λ λ²μ μμλ λ°±κ·ΈλΌμ΄λ μλΉμ€μ λν μ μ½μ΄ κ°νλμ΄ WorkManagerμ κ°μ λ체 λ°©μμ κΆμ₯νκ³ μμ΅λλ€.
μλΉμ€λ μ±μ ꡬ쑰μ μ±λ₯μ ν° μν₯μ λ―ΈμΉ μ μμΌλ―λ‘, μν©μ λ§λ μ΅μ μ λ°©μμ μ ννμ¬ ν¨μ¨μ μΌλ‘ ꡬννλ κ²μ΄ κ°μ₯ μ€μν©λλ€.
μλλ‘μ΄λ κ°λ°μ λ‘λλ§΅μ λ°λΌ μ 리ν λ΄μ©μ
λλ€.
'π» Programming > Android Developer AtoZ' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Android] App Components - (5) Content Provider μλ²½ κ°μ΄λ (2) | 2025.03.24 |
---|---|
[Android] App Components - (4) Broadcast Receiver μλ²½ κ°μ΄λ (0) | 2025.03.21 |
[Android] App Components (2) - Activity μλ²½ κ°μ΄λ (1) | 2025.03.05 |
[Android] App Components (1) - μλλ‘μ΄λ 4λ μ»΄ν¬λνΈ (0) | 2025.02.28 |
[Android] Operating System (2) - GCμ OOM Killer (1) | 2025.02.22 |