티스토리 뷰

반응형
SMALL

 

Reactive X 는 비동기 처리, Observable를 이용 하여 이벤트를 처리 하기 위한 라이브러리

 

Example >

startGameDate = "2020-04-02 15:30:00"

 

currentDate = 2020-03-31 11:00:00 일 경우 

출력은 2일 15시 30분 

 

currentDate = 2020-04-01 11:00:00 일 경우 

출력은 내일 15시 30분

 

currentDate = 2020-04-02 11:00:00 일 경우 

출력은 오늘 15시 30분

 

currentDate = 2020-04-01 15:00:00 일 경우 

출력은 남은시간 30 : 00 ( CountDown 시작, 한시간안에 들어왔을 경우 )  

 

currentDate = 2020-04-01 16:00:00 일 경우 

출력은 곧 게임이 옵니다 기다려 주세요.

 

 

반응형

 

class MainActivity : AppCompatActivity() {

    private val startGameDate = "2020-04-02 15:30:00"   // 이벤트가 시작 되는 날짜
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.KOREA)

    private val startDate by lazy { dateFormat.parse(startGameDate) }   // 게임이 시작 되는 시간
    private val currentDate by lazy { Date(System.currentTimeMillis()) }    // 현재 시간

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 게임 시간이 정해져 있기 때문에 현재 시간을 가져와 정해져 있는 시간과 비교 하여 화면을 구분함.
        val diff: Long = startDate.time - currentDate.time
        var seconds = diff / 1000   // 초로 계산됨 ( 양수일 경우 D-DAY 로 표시, 음수일 경우 바로 시작 )

        Observable
            .just(seconds)
            .flatMap (this::setChoiceTime)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                tv_time.text = it
                // TODO 0초가 되었을 때 Delay 를 줘야 할까 ??
                if (seconds == 0L) {
                    tv_time.text = "시간이 넘어 갔으니 페이지 전환하는 로직 필요."
                }
            }
    }

    private fun setChoiceTime(sTime: Long): Observable<String> {
        var seconds = sTime;
        val startTimeCalendar by lazy { Calendar.getInstance().apply { time = startDate } }

        return if (seconds < 0) {
            // 시간이 지났으니 다음 게임에 참여
            Observable.just("곧 게임이 올라옵니다! 기다려주세요.")
        } else {
            val day = ((startDate.time - currentDate.time) / (24*60*60*1000)).toInt()   // 여기서 day 는 무조건 양수
            val fixedDate = String.format("%02d", startTimeCalendar.get(Calendar.HOUR_OF_DAY)) + "시 " + String.format("%02d", startTimeCalendar.get(Calendar.MINUTE)) + "분"

            if (day > 0) {
                val printDay = if (day == 1) "내일 " else day.toString()+"일 "
                Observable.just(printDay + fixedDate)
            } else {
                val hours = TimeUnit.SECONDS.toHours(seconds) - day * 24
                if (hours > 0) {
                    Observable.just("오늘 $fixedDate")
                } else {
                    if (seconds >= 0L) {
                        Observable
                            .timer(1, TimeUnit.SECONDS)
                            .subscribeOn(io())
                            .repeat( seconds )
                            .map {
                                seconds -= 1
                                val minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toHours(seconds) * 60
                                val second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toMinutes(seconds) * 60
                                "남은 시간 " + String.format("%02d", minute) +" : "+ String.format("%02d", second)
                            }
                            .doOnUnsubscribe { Log.d("####", "자원해제") }
                    } else {
                        Observable.just("당일 게임이 끝났는지 여부와 시작하고 몇시까지 참여할 수 있는지 확인 후 여기에 로직이 들어가야 함.")
                    }
                }
            }
        }
    }

}

 

 

//TODO 

1. 시간을 계속 체크해서 남은시간이 한시간 안쪽으로 들어왔을 경우 카운트 다운을 시작 할 수 있게 

2. 시간이 00 : 00 이 되었을 때 이벤트

3. 비동기로 처리하는 로직인 만큼, 선언된 Activity 가 사라지거나 화면이 전환 되었을 때 필요한 해제 기능이 빠져있음.

 

나름대로 코드를 간소화 해봤지만 점점 코드를 더 간소화 하게 만들면 좋을 것 같음.

반응형
LIST
댓글