일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- dangling pointer
- randtbl
- JOP
- elf 헤더
- patchelf
- ioploaddrivers
- top chunk
- pwndbg
- fastbin
- libc-database
- libc.so
- RAO
- windows kernel
- house of force
- frida-dump
- Android
- WinDBG
- ntwritefile
- cmake
- sgerrand
- HOS
- kaslr
- SCP
- 계산기
- return to libraty
- canary leak
- kernel debug
- brop
- PLT
- windows
- Today
- Total
sh711 님의 블로그
안드로이드 네이티브 계산기 앱 개발 - 1 본문
1. 환경 세팅
아래 링크에서 android studio를 설치한다.
https://developer.android.com/studio?hl=ko
Android 스튜디오 및 앱 도구 다운로드 - Android 개발자 | Android Studio | Android Developers
Android Studio provides app builders with an integrated development environment (IDE) optimized for Android apps. Download Android Studio today.
developer.android.com
참고로 나는 koala 버전을 사용하여 개발을 진행하였다.

설치가 완료되면 File -> New -> New Project 를 선택한다

Empty Views Activity를 선택하고 Next 클릭

프로젝트 이름은 "calculator"로 하고 언어는 kotlin 호환되는 SDK는 API 29까지로 정했다
Finish 클릭

SDK manager에서 NDK Tools 를 설치해준다

C:\Users\계정ID\AppData\Local\Android\Sdk\ndk 디렉터리에 다음과 같이 NDK 이 설치된 것을 확인할 수 있다

이어서, Gradle Scripts 하위 Local.properties 에서 NDK 경로를 설정해준다

2. UI 구현
UI는 iOS 계산기와 비슷하게 만들어보려고 한다.

LiveData를 이용해 result TextView의 값이 변하면 observe를 통해 탐지하여 UI를 변화시킬 것이다

현재 tvResult는 viewModel.result에 연동되있는 상태이다.
<data>
<variable
name="viewModel"
type="com.test.calculator.CalculatorViewModel" />
</data>
...
...
...
<TextView
android:id="@+id/tvResult"
android:text="@{viewModel.result}"
android:textColor="@color/white"
android:textSize="40sp"
android:textStyle="bold"
android:gravity="right"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginHorizontal="15dp">
</TextView>
ViewModel 클래스
class CalculatorViewModel : ViewModel() {
private val _result = MutableLiveData<String>("")
private val _input = MutableLiveData<String>("input")
val result: LiveData<String> get() = _result
val input: LiveData<String> get() = _input
}
이제 버튼 클릭 시 tvResult 에 변화를 줘보자
// MainActivity
package com.test.calculator
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.hyunho.calc.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var calculatorViewModel: CalculatorViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val decorView = window.decorView
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
calculatorViewModel = ViewModelProvider(this).get(CalculatorViewModel::class.java)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.viewModel = calculatorViewModel // XML의 viewModel에 ViewModel 객체 연결
binding.lifecycleOwner = this
calculatorViewModel.result.observe(this, Observer { newResult ->
if (newResult.toString().length > 14) {
Toast.makeText(this, "입력 초과입니다!!!", Toast.LENGTH_SHORT).show()
calculatorViewModel.deleteResult()
}
else {
binding.tvResult.text = newResult
}
})
val numMap = mapOf(
binding.num1 to "1",
binding.num2 to "2",
binding.num3 to "3",
binding.num4 to "4",
binding.num5 to "5",
binding.num6 to "6",
binding.num7 to "7",
binding.num8 to "8",
binding.num9 to "9",
binding.num0 to "0",
)
numMap.forEach { (button, number) ->
button.setOnClickListener {
calculatorViewModel.operand(number)
}
}
val operMap = mapOf(
binding.plus to "+",
binding.minus to "-",
binding.multiply to "x",
binding.divide to "/",
binding.mod to "%",
binding.point to ".",
)
operMap.forEach { (button, operation) ->
button.setOnClickListener {
calculatorViewModel.operator(operation)
}
}
binding.reverse.setOnClickListener {
calculatorViewModel.reverse()
}
binding.delete.setOnClickListener {
calculatorViewModel.deleteResult()
}
binding.AC.setOnClickListener {
calculatorViewModel.allClear()
}
}
}
ViewModel 클래스에 함수 선언
// CalculatorViewModel
package com.test.calculator
import android.content.ContentValues.TAG
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class CalculatorViewModel : ViewModel() {
private val _result = MutableLiveData<String>("")
private val _input = MutableLiveData<String>("input")
val result: LiveData<String> get() = _result
val input: LiveData<String> get() = _input
fun operand(number: String) {
if(_result.value == "0") {
_result.value = number
} else {
_result.value = _result.value + number
}
}
fun operator(op: String) {
if (_result.value == "0" || _result.value == "")
if (op == "-") {
_result.value = "-"
} else {
_result.value = ""
}
else {
_result.value = _result.value + op
}
}
fun result(result: String) {
_result.value = result
}
fun deleteResult() {
_result.value = _result.value?.dropLast(1)
}
fun allClear() {
_result.value = ""
_input.value = "input"
}
fun reverse() {
val currentInput = _result.value ?: return // 현재 결과값이 없다면 리턴
val regex = "[-+]?\\d+$".toRegex() // 마지막 숫자와 부호를 찾는 정규식
val matchResult = regex.find(currentInput)
if (matchResult != null) {
val lastNumber = matchResult.value // 마지막 숫자 추출
// 부호를 반전
val reversed = if (lastNumber.startsWith("-")) {
lastNumber.replaceFirst("-", "+")
} else if (lastNumber.startsWith("+")) {
lastNumber.replaceFirst("+", "-")
} else {
"+$lastNumber"
}
// 마지막 숫자만 변경하여 업데이트
_result.value = currentInput.replace(lastNumber, reversed)
}
}
}
이제 기본적인 UI와 LiveData는 완성되었다.

다음 글에서 JNI 연동 및 네이티브 함수를 통해 연산하는 코드 작성을 해보겠다.
'Development > Android' 카테고리의 다른 글
안드로이드 네이티브 계산기 앱 개발 - 2 (0) | 2025.03.03 |
---|