반응형
Service
설명
- 백그라운드 처리를 위해 제공되는 요소
- 일반 서비스는 메모리 부족해질 경우 OS에 의해 제거된다. 이를 방지하기 위해 Foreground Service가 있다.
코드
manifests/AndroidManifest.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android_example">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Androidexample">
<service
android:name=".TestService"
android:enabled="true"
android:exported="true" />
<activity android:name=".MainActivity">
<intent-filter>
<!-- Entry Point -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
undefinedcopy
TestService
class TestService : Service() {
override fun onBind(intent: Intent): IBinder {
TODO("Return the communication channel to the service.")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
var builder: NotificationCompat.Builder? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel("test1", "Service", NotificationManager.IMPORTANCE_HIGH)
channel.enableLights(true)
channel.lightColor = Color.RED
channel.enableVibration(true)
manager.createNotificationChannel(channel)
builder = NotificationCompat.Builder(this, "test1")
} else {
builder = NotificationCompat.Builder(this)
}
builder?.setSmallIcon(android.R.drawable.ic_menu_search)
builder?.setContentTitle("서비스 가동")
builder?.setContentText("서비스가 가동중입니다.")
val notification = builder?.build()
startForeground(10, notification)
val thread = MyThread()
thread.start()
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d("TestService", "onDestroy")
}
inner class MyThread : Thread() {
override fun run() {
var index = 0
while (index < 3) {
SystemClock.sleep(2000)
Log.d("TestService", index.toString())
index++
}
}
}
}
undefinedcopy
MainActivity
class MainActivity : AppCompatActivity() {
private var serviceIntent: Intent? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val startButton = findViewById<Button>(R.id.startButton)
val stopButton = findViewById<Button>(R.id.stopButton)
startButton.setOnClickListener {
serviceIntent = Intent(this, TestService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent)
} else {
startService(serviceIntent)
}
}
stopButton.setOnClickListener {
stopService(serviceIntent)
}
}
}
undefinedcopy
참고
IPC
설명
- Activity에서 실행 중인 서비스의 데이터를 사용하고자 할 때 사용하는 개념
코드
TestServiceclass TestService : Service() {
private var value = 0
private var thread: Thread? = null
private val binder: IBinder = LocalBinder()
override fun onBind(intent: Intent): IBinder {
return binder
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
thread = MyThread()
thread?.start()
return super.onStartCommand(intent, flags, startId)
}
inner class LocalBinder : Binder() {
fun getService(): TestService {
return this@TestService
}
}
inner class MyThread : Thread() {
override fun run() {
while (true) {
SystemClock.sleep(2000)
Log.d("TestService", value.toString())
value++
}
}
}
fun getValue(): Int {
return value
}
}
undefinedcopy
MainActivity
class MainActivity : AppCompatActivity() {
private var testService: TestService? = null
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as TestService.LocalBinder
testService = binder.getService()
}
override fun onServiceDisconnected(name: ComponentName?) {
testService = null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
val intent = Intent(this, TestService::class.java)
if (!isServiceRunning("com.example.android_example.TestService")) {
startService(intent)
}
bindService(intent, connection, Context.BIND_AUTO_CREATE) // BIND_AUTO_CREATE : 서비스가 가동중이 아니면 가동 후 bind 처리
button.setOnClickListener {
val value = testService?.getValue()
Toast.makeText(this, value.toString(), Toast.LENGTH_SHORT).show()
}
}
override fun onDestroy() {
super.onDestroy()
unbindService(connection)
}
private fun isServiceRunning(name: String): Boolean {
val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
for (service: ActivityManager.RunningServiceInfo in manager.getRunningServices(Int.MAX_VALUE)) {
if (service.service.className.equals(name)) {
return true
}
}
return false
}
}
undefinedcopy
참고
반응형
'Development > Android' 카테고리의 다른 글
[Android] Resources (0) | 2021.02.09 |
---|---|
[Android] SQLite (0) | 2021.02.09 |
[Android] BroadcastReceiver (0) | 2021.02.09 |
[Android] Thread & Handler (0) | 2021.02.09 |
[Android] DialogFragment (0) | 2021.02.09 |