Agera(在瑞典话里是“行动”的意思)是一个特别轻量级的 Android 库,它能够帮助你为受生命周期影响的 Android 的应用组件(例如 Activies)以及在这件组件中的对象(如 Views)准备数据。它引入了一种函数响应式编程的风格,能够促进分离“何时”、“何处”、“何事”,这是数据处理流程当中的三个主要因素,通过分离实现了用一个表达式描述将一个复杂、异步的流程,而且接近于自然与然。
下面是一个展示 Agera 的事例。本 wiki 以及 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); setContentView(R.layout.activity_main); backgroundView = (ImageView) findViewById(R.id.background); // 创建一个含有图片请求的结果的源,但是根据 // 联网请求符合显示尺寸的图片 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(); // compile 构建请求 } }) // Supply an HttpRequest based on the display size .goTo(NETWORK_EXECUTOR) // 在网络请求线程执行 .attemptTransform(httpFunction()) // 获取 HTTP 请求实例 .orSkip() // 请求失败时跳过 .goTo(DECODE_EXECUTOR) // 进入解码线程解码 .thenTransform(new Function<HttpResponse, Result<Bitmap>>() { // HttpResponse 转 Result<Bitmap> @NonNull @Override public Result<Bitmap> apply(@NonNull HttpResponse response) { byte[] body = response.getBody(); return absentIfNull(decodeByteArray(body, 0, body.length)); } }) .onDeactivation(SEND_INTERRUPT) // 源不活动时的行为, .compile(); // 创建源 } @Override protected void onResume() { super.onResume(); // 启动源的监听,触发流程 // 将 Activity 自己作为 Updatable 添加进去 // 图片加载成功后会调用其 update 方法 background.addUpdatable(this); } @Override protected void onPause() { super.onPause(); // 停止源的监听,中止其活动 background.removeUpdatable(this); } @Override public void update() { // 源更新时调用 // 从源中拿去图片,并进行发送(调用自己的 Accept) background.get().ifSucceededSendTo(this); } @Override public void accept(@NonNull Bitmap background) { // 将获取结果设置显示到界面上 backgroundView.setImageBitmap(background); } }