RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리

Post on 22-Jan-2018

1.969 views 1 download

Transcript of RxAndroid: 비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리

RxAndroid 세미나

Create by COWKITE

http://cowkite.com

비동기 및 이벤트 기반 프로그래밍을 위한 라이브러리

03 Rx와 Android Android에 Rx 도입하기

INDEX

01 개요 Android에서의 Rx 사용 필요성

02 Rx 사용하기 Rx 개념과 사용법 소개

01 개요

01-1. 말만 쉬운 시나리오 01-2. Rx는 어떻게 문제를 해결할까?

Android에서의 Rx 사용 필요성

5

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

7

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서 ArrayList<File> fileList = getGallryFile();

9

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서 촬영날짜가 1년 이내인 항목의 ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

11

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서 촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다. ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

13

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다. ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

15

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

17

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

19

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

21

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

23

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

25

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

26

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

27

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

28

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

29

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를 필요한 데이터만 걸러내면서

30

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를 필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

31

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

32

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

33

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

원하는 시점에 자유롭게 취소할 수도 있으며

34

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

원하는 시점에 자유롭게 취소할 수도 있으며

모든 에러에 대한 예외처리가 가능해야 한다.

35

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

원하는 시점에 자유롭게 취소할 수도 있으며

테스트는 쉽고

모든 에러에 대한 예외처리가 가능해야 한다.

36

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

원하는 시점에 자유롭게 취소할 수도 있으며

테스트는 쉽고

반복되는 코드들은 생략하면서

모든 에러에 대한 예외처리가 가능해야 한다.

37

01_1 말만 쉬운 시나리오

RxAndroid 세미나

갤러리 목록에서 최근에 촬영한 파일 이름 가져오기

갤러리 목록에서

파일 개수가 1만장이기 때문에 background thread에서 처리하되

촬영날짜가 1년 이내인 항목의 파일 이름만 출력한다.

결과는 view에 출력하기 위해 main thread에서 받는다.

이 조건들을 복잡하지 않고 쉽게 코딩 할 수 있을까?

사용자가 back key를 누르면 즉시 수행을 멈춰야하고

기능 하나하나씩 모듈 테스트를 할 수 있도록 코딩 해야 하며

중복 코드는 없도록 하면서

모든 예외상항에서 오류 팝업을 띄우도록 예외처리가 되어야 한다.

ArrayList<File> fileList = getGallryFile(); ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { } }

ArrayList<File> fileList = getGallryFile(); for(File file : fileList) { if(isWithin1Year(file.date)) { // TODO file.name } }

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { // TODO file.name } } } }; thread.start();

Thread thread = new Thread() { @Override public void run() { ArrayList<File> fileList = getGallryFile(); for (File file : fileList) { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { // TODO file.name } }); } } } }; thread.start();

public void onBackPressed() { thread.sleep(1000); }

Thread thread = new Thread() { @Override public void run() { try { ArrayList<File> fileList = getGallryFile(); if (fileList == null || fileList.size() <= 0) { showErrorPopup(); } else { for (File file : fileList) { if (file.date == null) { showErrorPopup(); } else { if (isWithin1Year(file.date)) { runOnUiThread(new Runnable() { @Override public void run() { if (file.name == null) { showErrorPopup(); } else { // TODO file.name } } }); } } } } } } catch(Exception e) { showErrorPopup(); } }; thread.start();

???

?????

???????

특정 데이터를

액션은 A thread 에서 하지만

필요한 데이터만 걸러내면서 원하는 type으로 결과를 받고

결과는 B thread에서 받아야 한다.

원하는 시점에 자유롭게 취소할 수도 있으며

테스트는 쉽고

반복되는 코드들은 생략하면서

모든 에러에 대한 예외처리가 가능해야 한다.

코드도 쉬워야 한다.

38

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

39

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

41

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

45

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고 유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

46

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Reactive System

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

47

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

48

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

49

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

51

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

53

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

push-scenario

54

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

push-scenario

Observable

57

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

push-scenario

LINQ

코드 상에서 데이터를 질의할 때 쿼리처럼 표현할 수 있도록 도와주는 확장 문법

Observable

Data collection에 대한 복잡한 절차적 질의를 간결하게 변경 가능

58

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

push-scenario

LINQ

코드 상에서 데이터를 질의할 때 쿼리처럼 표현할 수 있도록 도와주는 확장 문법

Observable

Data collection에 대한 복잡한 절차적 질의를 간결하게 변경 가능 var data = from num in numbers where num % 2 == 0 orderby num select num;

59

Environment

01_2 Rx는 어떻게 문제를 해결할까?

RxAndroid 세미나

Observable과 LINQ와 Scheduler

반응적(Responsive)이고

Program

Reactive System

수동성 반응을 획득하는 시스템

유연(Resilient)하며 탄력적(Elastic)인 메시지 기반(Message-driven)의 시스템

pull-scenario

push-scenario

LINQ

코드 상에서 데이터를 질의할 때 쿼리처럼 표현할 수 있도록 도와주는 확장 문법

Observable

Data collection에 대한 복잡한 절차적 질의를 간결하게 변경 가능

Operator

var data = from num in numbers where num % 2 == 0 orderby num select num;

02 Rx 사용하기

01-1. 기본적인 사용법 01-2. Rx의 연산자 01-3. Rx + Lambda

Rx 개념과 사용법 소개

62

02_1 기본적인 사용법

RxAndroid 세미나

Observer와 Observable을 연결하는 subscriber

63

02_1 기본적인 사용법

RxAndroid 세미나

Observer와 Observable을 연결하는 subscriber

// 메소드를 호출하고, 리턴 값을 value에 할당한다 value = someMethod(parameters); // value를 통해 필요한 작업을 진행한다

67

def onNext = { item -> /* 필요한 연산을 처리한다 */ }; def onError = { throwable -> /* 실패한 호출에 대응한다 */ }; def onComplete = { /* 최종 응답 후 정리 작업을 한다 */ }; def observable = someMethod(parameters); observable.subscribe(onNext, onError, onComplete); // 필요한 코드를 구현한다

02_1 기본적인 사용법

RxAndroid 세미나

Observer와 Observable을 연결하는 subscriber

// 메소드를 호출하고, 리턴 값을 value에 할당한다 value = someMethod(parameters); // value를 통해 필요한 작업을 진행한다

Observer: 결과를 수신

Observable: 데이터를 발생

발생되는 데이터에 결과 연결

69

def onNext = { item -> /* 필요한 연산을 처리한다 */ }; def onError = { throwable -> /* 실패한 호출에 대응한다 */ }; def onComplete = { /* 최종 응답 후 정리 작업을 한다 */ }; def observable = someMethod(parameters); observable.subscribe(onNext, onError, onComplete); // 필요한 코드를 구현한다

02_1 기본적인 사용법

RxAndroid 세미나

Observer와 Observable을 연결하는 subscriber

// 메소드를 호출하고, 리턴 값을 value에 할당한다 value = someMethod(parameters); // value를 통해 필요한 작업을 진행한다

Observer: 결과를 수신

Observable: 데이터를 발생

발생되는 데이터에 결과 연결

JAVA에서의 Hello world!

Observable.from(new String[]{"Hello", "world!"}).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });

71

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

72

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

74

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

76

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

Observable 생성 연산자

새로운 Observable을 만드는 연산자

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

78

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

Observable 생성 연산자

새로운 Observable을 만드는 연산자

Observable 필터링 연산자

Observable에서 선택적으로 항목을 배출하는 연산자

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

80

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

Observable 생성 연산자

새로운 Observable을 만드는 연산자

Observable 변환 연산자

Observable의 결과값을 변환하는 연산자

Observable 필터링 연산자

Observable에서 선택적으로 항목을 배출하는 연산자

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

81

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

Observable 생성 연산자

새로운 Observable을 만드는 연산자

Observable 변환 연산자

Observable의 결과값을 변환하는 연산자

Observable 필터링 연산자

Observable에서 선택적으로 항목을 배출하는 연산자

Observable 결합 연산자

여러 개의 Observable들을 하나의 Observable로 만드는 연산자

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

82

Observable.from(users).filter(user -> user.id != null).map(User::getName).toList();

02_2 Rx의 연산자

RxAndroid 세미나

다양한 연산자와 연산자들을 잇는 연산자 체인

Observable 생성 연산자

새로운 Observable을 만드는 연산자

Observable 변환 연산자

Observable의 결과값을 변환하는 연산자

Observable 필터링 연산자

Observable에서 선택적으로 항목을 배출하는 연산자

Observable 유틸리티 연산자

Observable과 함께 동작하는 도우미 연산자

Observable 결합 연산자

여러 개의 Observable들을 하나의 Observable로 만드는 연산자

users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업 users 데이터 중에서 user.id가 null이 아닌 user들의 이름을 리스트업

84

02_3 Rx + Lambda

RxAndroid 세미나

함수형 프로그래밍을 지원하는 Lambda

85

02_3 Rx + Lambda

RxAndroid 세미나

함수형 프로그래밍을 지원하는 Lambda

mToolbar.getLeftIcon().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mActivity.finish(); } });

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { textView.setText(countText); } });

86

02_3 Rx + Lambda

RxAndroid 세미나

함수형 프로그래밍을 지원하는 Lambda

mToolbar.getLeftIcon().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mActivity.finish(); } });

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { textView.setText(countText); } });

87

02_3 Rx + Lambda

RxAndroid 세미나

함수형 프로그래밍을 지원하는 Lambda

mToolbar.getLeftIcon().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mActivity.finish(); } });

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { textView.setText(countText); } });

Observable.from(new String[]{"Hello", "world!"}).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });

89

02_3 Rx + Lambda

RxAndroid 세미나

함수형 프로그래밍을 지원하는 Lambda

mToolbar.getLeftIcon().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mActivity.finish(); } });

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { textView.setText(countText); } });

Observable.from(new String[]{"Hello", "world!"}).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });

Observable.from(new String[]{"Hello", "world!"}).subscribe(System.out::println);

Lambda

03 Rx와 Android

01-1. UI 다루기 01-2. RxAndroid X Realm 01-3. RxAndroid X Retrofit 01-4. Rx와 Android

Android에 Rx 도입하기

92

03_1 UI 다루기

RxAndroid 세미나

Observable과 연산자를 합성하여 UI 구조화하기

95

03_1 UI 다루기

RxAndroid 세미나

Observable과 연산자를 합성하여 UI 구조화하기

RxView.clicks(findViewById(R.id.button)) .map(event -> new Random().nextInt()) .subscribe(value -> { textView.setText("number: " + value.toString()); }, throwable -> { Log.e(TAG, "Error: " + throwable.getMessage()); throwable.printStackTrace(); });

클릭의 추상화

이벤트 발생시 랜덤 추출하여 출력

99

03_1 UI 다루기

RxAndroid 세미나

Observable과 연산자를 합성하여 UI 구조화하기

RxView.clicks(findViewById(R.id.button)) .map(event -> new Random().nextInt()) .subscribe(value -> { textView.setText("number: " + value.toString()); }, throwable -> { Log.e(TAG, "Error: " + throwable.getMessage()); throwable.printStackTrace(); });

Observable<String> lefts = RxView.clicks(leftButton).map(event -> "left"); Observable<String> rights = RxView.clicks(rightButton).map(event -> "right"); Observable<String> together = Observable.merge(lefts, rights); together.subscribe(text -> textView.setText(text)); together.map(text -> text.toUpperCase()).subscribe(text -> showToast(text));

클릭의 추상화

이벤트 발생시 랜덤 추출하여 출력

Observable 병합

마지막 이벤트 값 출력

발생 항목 대문자로 변환하여 출력

104

03_1 UI 다루기

RxAndroid 세미나

Observable과 연산자를 합성하여 UI 구조화하기

RxView.clicks(findViewById(R.id.button)) .map(event -> new Random().nextInt()) .subscribe(value -> { textView.setText("number: " + value.toString()); }, throwable -> { Log.e(TAG, "Error: " + throwable.getMessage()); throwable.printStackTrace(); });

Observable<String> lefts = RxView.clicks(leftButton).map(event -> "left"); Observable<String> rights = RxView.clicks(rightButton).map(event -> "right"); Observable<String> together = Observable.merge(lefts, rights); together.subscribe(text -> textView.setText(text)); together.map(text -> text.toUpperCase()).subscribe(text -> showToast(text));

클릭의 추상화

이벤트 발생시 랜덤 추출하여 출력

Observable 병합

마지막 이벤트 값 출력

발생 항목 대문자로 변환하여 출력

Observable 컴바인

건물명과 주소명이 모두 검색되어야 활성화 건물명

지번 주소 선택

GooglePlaceAPI

GeoAddress

106

03_2 RxAndroid X Realm

RxAndroid 세미나

DB 모듈 라이브러리, Realm을 Rx와 같이 사용하기

113

03_2 RxAndroid X Realm

RxAndroid 세미나

DB 모듈 라이브러리, Realm을 Rx와 같이 사용하기

기존의 DB보다 빠른 속도

https://realm.io/kr/news/gdg-seoul-realm-introduce/

오픈 소스

뛰어난 사용성

SQLite는 객체를 그대로 DB에 저장할 수 없으므로, 테이블 간의 관계를 고민하며 스키마를 구성해야 하며 조인 쿼리를 필수로 사용해야 함. 하지만 Realm은 테이블 간의 관계를 has로 표현하여, 설계와 쿼리를 덜 고민하도록 함

AES-256 암호화를 지원

기본적인 데이터 입출력인 모델, 쓰기, 읽기, 일반적인 쿼리 등을 제공

114

03_2 RxAndroid X Realm

RxAndroid 세미나

DB 모듈 라이브러리, Realm을 Rx와 같이 사용하기

realm.where(Person.class).equalTo("name", "John").findAllAsync().asObservable() .filter(new Func1<RealmResults<Person>, Boolean>() { @Override public Boolean call(RealmResults<Person> persons) { // Ignore unloaded results return persons.isLoaded(); } }) .subscribe(new Action1<RealmResults<Person>>() { @Override public void call(RealmResults<Person> persons) { // Show persons... } });

기존의 DB보다 빠른 속도

https://realm.io/kr/news/gdg-seoul-realm-introduce/

오픈 소스

뛰어난 사용성

SQLite는 객체를 그대로 DB에 저장할 수 없으므로, 테이블 간의 관계를 고민하며 스키마를 구성해야 하며 조인 쿼리를 필수로 사용해야 함. 하지만 Realm은 테이블 간의 관계를 has로 표현하여, 설계와 쿼리를 덜 고민하도록 함

AES-256 암호화를 지원

기본적인 데이터 입출력인 모델, 쓰기, 읽기, 일반적인 쿼리 등을 제공

116

03_3 RxAndroid X Retrofit

RxAndroid 세미나

네트워크 모듈 라이브러리, Retrofit을 Rx와 같이 사용하기

122

03_3 RxAndroid X Retrofit

RxAndroid 세미나

네트워크 모듈 라이브러리, Retrofit을 Rx와 같이 사용하기

쉬운 네트워크 관리

네트워크 통신 연결/해제에 대한 관리

Annotation으로 이루어진 매개변수

자유로운 parsing

원하는 포맷에 맞게 데이터 요청 및, parsing 하여 응답 받기 가능

동기 / 비동기 방식 쉽게 선택 가능

124

03_3 RxAndroid X Retrofit

RxAndroid 세미나

네트워크 모듈 라이브러리, Retrofit을 Rx와 같이 사용하기

Retrofit retrofit = new Retrofit.Builder() .baseUrl("serverUrl") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build();

public interface SomeAPI { @GET("user") Observable<User> getUser(); }

쉬운 네트워크 관리

네트워크 통신 연결/해제에 대한 관리

Annotation으로 이루어진 매개변수

자유로운 parsing

원하는 포맷에 맞게 데이터 요청 및, parsing 하여 응답 받기 가능

동기 / 비동기 방식 쉽게 선택 가능

126

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

127

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

단점

131

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점

133

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점

136

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점

138

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점

139

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점 장점

143

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 다양한 비동기처리 상황에 유리하다.

• 순차적으로 실행되는 비동기 통신

• 복수의 비동기 처리 완료 후 결과 값을 합칠 때

• 연속 클릭 이벤트 발생으로 인한 이벤트 중복실행 제어

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

단점 장점

146

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 다양한 비동기처리 상황에 유리하다.

• 순차적으로 실행되는 비동기 통신

• 복수의 비동기 처리 완료 후 결과 값을 합칠 때

• 연속 클릭 이벤트 발생으로 인한 이벤트 중복실행 제어

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

2. 콜백 지옥에서 탈출시켜준다.

• unsubscriber 호출로 인한 콜백 해제

• 모든 비동기 동작은 Observable<T> 타입

단점 장점

148

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 다양한 비동기처리 상황에 유리하다.

• 순차적으로 실행되는 비동기 통신

• 복수의 비동기 처리 완료 후 결과 값을 합칠 때

• 연속 클릭 이벤트 발생으로 인한 이벤트 중복실행 제어

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

2. 콜백 지옥에서 탈출시켜준다.

• unsubscriber 호출로 인한 콜백 해제

• 모든 비동기 동작은 Observable<T> 타입

3. 스레드 관리가 편리해진다.

• 다양한 Thread 관리 형식 지원

단점 장점

152

03_4 Rx와 Android

RxAndroid 세미나

Rx를 Android에 도입했을 때 단점과 장점

3. Android에 바로 사용할 수 없다.

• Java + Kotlin/Scala…

• Java8 + Lambda

4. Memory leak 관리에 유의해야 한다.

• subscriber 사용에 뒤따르는 unsubscriber

2. 코드가 오히려 더 복잡해질 수 있다.

• 써야 할 때와 쓰면 안될 때를 구분하는 것에 유의

1. 다양한 비동기처리 상황에 유리하다.

• 순차적으로 실행되는 비동기 통신

• 복수의 비동기 처리 완료 후 결과 값을 합칠 때

• 연속 클릭 이벤트 발생으로 인한 이벤트 중복실행 제어

1. 진입장벽이 높다.

• Rx식의 Multi-threading 과 함수형 프로그래밍의 개념 이해

• 너무 다양한 operator의 제공으로 인한 러닝 커브

• Reactive programming뿐 아니라 Reactive architecture까지

2. 콜백 지옥에서 탈출시켜준다.

• unsubscriber 호출로 인한 콜백 해제

• 모든 비동기 동작은 Observable<T> 타입

3. 스레드 관리가 편리해진다.

• 다양한 Thread 관리 형식 지원

4. 코드가 깔끔해진다.

• Lambda 사용 시 보일러 플레이트 코드 제거 가능

• 통일된 방식으로 Event, Thread, Time, Exception 처리 방법 제공

• 외부에 제공할 수 있는 읽기 전용의 Observable

단점 장점

THANK YOU

http://cowkite.com

http://www.linkedin.com/in/cowkite

COWKITE