-
Notifications
You must be signed in to change notification settings - Fork 3
Home
Seong-Ug Steve Jung edited this page Apr 21, 2016
·
3 revisions
Agera (스웨덴어로 to act
) 안드로이드 어플리케이션의 Activity
와 같은 컴포넌트나 그 내부의 View
나 그와 유사한 Life-Cycle
을 가진 객체들이 데이터를 이용하기 쉽게 돕기 위해 제작된 라이브러리입니다. Functional-Reactive-Programming
의 한 종류로 자연어에 가까운 상태로 When
, Where
, What
요소들을 깔끔하게 분리시켜주며 단일 표현을 위해 복잡하고 비동기적 처리를 할 수 있습니다.
아래 예제 코드를 통해 Agera
를 특징을 확인하실 수 있습니다. 앞으로 위키를 통해서 javadoc
과 agera
의 동작을 설명하도록 하겠습니다.
public class AgeraActivity extends Activity implements Receiver<Bitmap>, Updatable {
private static final ExecutorService NETWORK_EXECUTOR = newSingleThreadExecutor();
private static final ExecutorService DECODE_EXECUTOR = newSingleThreadExecutor();
private Repository<Result<Bitmap>> background;
private ImageView backgroundView;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Layout 바인딩
setContentView(R.layout.activity_main);
// 배경 View 바인딩
backgroundView = (ImageView) findViewById(R.id.background);
// 비트맵 요청의 결과를 보관할 저장소(repository) 를 생성합니다.
// 화면 크기를 기반으로 네트워크를 통해 이미지를 가져오도록 하겠습니다.
background = repositoryWithInitialValue(Result.<Bitmap>absent())
.observe() // (옵션사항) 이벤트를 통해 이미지를 갱신합니다. 예제에서는 발생하지 않습니다.
.onUpdatesPerLoop() // 갱신은 매 Looper 마다 동작합니다. 물론 발생하지 않습니다.
.getFrom(new Supplier<HttpRequest>() {
@NonNull
@Override
public HttpRequest get() {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int size = Math.max(displayMetrics.heightPixels, displayMetrics.widthPixels);
return httpGetRequest(
"http://www.gravatar.com/avatar/4df6f4fe5976df17deeea19443d4429d?s=" + size)
.compile();
}
}) // 화면 크기에 맞춰 HttpRequest 를 생성합니다.
.goTo(NETWORK_EXECUTOR) // 네트워크 Thread-Executor 로 변경합니다.
.attemptTransform(httpFunction())
.orSkip() // http 요청이 실패하면 무시하도록 합니다.
.goTo(DECODE_EXECUTOR) // Decode Thread-Exector 로 변경합니다.
.thenTransform(new Function<HttpResponse, Result<Bitmap>>() {
@NonNull
@Override
public Result<Bitmap> apply(@NonNull HttpResponse response) {
byte[] body = response.getBody();
return absentIfNull(decodeByteArray(body, 0, body.length));
}
}) // 성공한 결과만 Decode 처리하고 실패시 전송하지 않습니다.
.onDeactivation(SEND_INTERRUPT) // 비동작 선언시 http request 와 decode 를 중단하도록 합니다.
.compile(); // 최종적으로 저장소(Repository)를 만듭니다.
}
@Override
protected void onResume() {
super.onResume();
background.addUpdatable(this); // 저장소로 부터 이벤트를 받도록 등록하고 flow 를 시작합니다.
}
@Override
protected void onPause() {
super.onPause();
background.removeUpdatable(this); // 저장소로부터 이벤트를 받지 않고 flow 가 중단되도록 합니다.
}
@Override
public void update() {
// Called as the repository is updated
background.get().ifSucceededSendTo(this); // 만약 정상적인 Bitmap 이 있다면 accept() 로 전달합니다.
}
@Override
public void accept(@NonNull Bitmap background) {
backgroundView.setImageBitmap(background); // View 의 배경에 Bitmap 을 설정합니다.
}
}