Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.
JoseAlcerreca edited this page Apr 19, 2016 · 19 revisions

Agera

Agera (Swedish for “to act”) is a super lightweight Android library that helps prepare data for consumption by the Android application components (such as Activities), or objects therein (such as Views), that have life-cycles in one form or another. It introduces a flavor of functional reactive programming, facilitates clear separation of the when, where and what factors of a data processing flow, and enables describing such a complex and asynchronous flow with a single expression, in near natural language.

Below is an sample demonstrating some of the features of Agera. This wiki together with the javadoc, explains how each part of Agera works.

    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);
        // Set the content view
        setContentView(R.layout.activity_main);

        // Find the background view
        backgroundView = (ImageView) findViewById(R.id.background);

        // Create a repository containing the result of a bitmap request. Initially absent, but
        // configured to fetch the bitmap over the network based on display size.
        background = repositoryWithInitialValue(Result.<Bitmap>absent())
            .observe() // Optionally refresh the bitmap on events. In this case, never
            .onUpdatesPerLoop() // Refresh per Looper thread loop. In this case, never
            .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();
              }
            }) // Supply an HttpRequest based on the display size
            .goTo(NETWORK_EXECUTOR) // Change execution to the network executor
            .attemptTransform(httpFunction())
            .orSkip() // Make the actual http request, skip on failure
            .goTo(DECODE_EXECUTOR) // Change execution to the decode executor
            .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 the successful http response to the result of a bitmap, absent on failure
            .onDeactivation(SEND_INTERRUPT) // Interrupt http request/decode on deactivation
            .compile(); // Create the repository
      }

      @Override
      protected void onResume() {
        super.onResume();
        background.addUpdatable(this); // Start listening to the repository, triggering the flow
      }

      @Override
      protected void onPause() {
        super.onPause();
        background.removeUpdatable(this); // Stop listening to the repository, deactivating it
      }

      @Override
      public void update() {
        // Called as the repository is updated
        background.get().ifSucceededSendTo(this); // If containing a valid bitmap, send to accept below
      }

      @Override
      public void accept(@NonNull Bitmap background) {
        backgroundView.setImageBitmap(background); // Set the background bitmap to the background view
      }
    }