两年前,推出RxJava。后来Square公司陆续推出RxAndroid、RxBus、RxBinding,把响应式编程发扬光大,深受开发者的喜爱。两年后,Google公司感觉不对劲,干脆自己推出全新的响应式编程,官方称之为Agera,这名字听起来有点奇怪。官方是这样解析的:Agera(瑞典文的意思是"采取行动")是一个超轻量级的Android库,帮助Android应用中有生命周期的组件(比如:Activities)或者组件中的对象(比如:Views)预准备数据。 通过加入函数式响应式编程,Agera可以在时机、线程和数据层面上更清晰的分离处理流程,并且使用一个接近自然语言的单个表达式就能编写一个复杂的异步流。
先看下与Agera相关的专业术语以及相关用法:
1、Updatable(Observer)
翻译为:观察者
用途:接收事件通知,更新数据。 说明:观察者模式中的Observer,在Agera中使用Updatable
public interface Updatable {
void update();
}
2、Observable
翻译为:被观察者、事件源
用途:作为事件源,通知观察者更新数据,可以注册、注销观察者。 说明:当事件发生的时候,调用dispatchUpdate()通知观察者。
public interface Observable {
void addUpdatable(@NonNull Updatable updatable);
void removeUpdatable(@NonNull Updatable updatable);
}
3、Supplier
翻译为:数据提供者
用途:get()新数据。
public interface Supplier<T> {
@NonNull
T get();
}
4、Repository
翻译为:Repository、数据仓库
用途:接收事件源、提供数据源的结合体。
public interface Repository<T> extends Observable, Supplier<T> {
}
5、Reactive programming
翻译为:响应式编程
说明:一种面向数据流和变化传播的编程范式。 这意味着在编程语言中很方便地表达静态或动态的数据流,
而相关的计算模型会自动将变化的值通过数据流进行传播。 例如:在命令式编程环境中,a = b + c 表示将表达式的结果赋给a,
而之后改变b或c的值不会影响a。但在响应式编程中,a的值会随着b或c的更新而更新。
6、Activation lifecycle
翻译为:激活生命周期
用途:注册观察者:数据仓库变为激活状态;注销观察者:数据仓库变为非激活状态。
7、Active
翻译为:激活状态、活动状态
8、Inactive
翻译为:非激活状态、非活动状态
9、worker Looper thread
翻译为:有Looper的线程
说明:Agera 内部消息是通过Handler来完成的,所有线程需要有Looper。
10、Data Processing Flow
翻译为:数据处理流程
11、When, Where, What
翻译为:什么时候(时机),什么线程上[执行],什么数据
12、compiled repository
翻译为:编译数据仓库
Agera提供的函数响应式编程包括五个方面:content、net、database、rvdatabinding、rvadapter。其中content对Broadcast与SharePreference进行观察,net基于HttpUrlConnection结合请求体与响应体的封装,database是基于sqlite进行数据的增删查改。因此需要在gradle里面导入依赖包:
compile 'com.google.android.agera:agera:1.2.0-beta3'
compile 'com.google.android.agera:content:1.2.0-beta3'
compile 'com.google.android.agera:database:1.2.0-beta3'
compile 'com.google.android.agera:net:1.2.0-beta3'
compile 'com.google.android.agera:rvadapter:1.2.0-beta3'
compile 'com.google.android.agera:rvdatabinding:1.2.0-beta3'
接下来看下ObservableLifeCycle,也就是观察者的生命周期:
从上图可看出,Updatable是一个先进先出的队列:当调用start方法时,会回调addUpdatable(this)方法把对象添加到队列;当调用stop方法时,则回调removeUpdatable(this)方法,把对象从队列中移除。而Observable负责观察,调用update()方法进行更新。
再来看下UILifeCycle,Activity里生命周期的回调:
在Activity执行onCreate方法时,调用init方法进行初始化;执行onStart方法时,调用addUpdatable方法添加到队列;执行onStop方法时,则调用removeUpdatable方法从队列里移除;最后Activity被销毁执行onDestroy方法,调用GC回收。
接下来应该是最激动人心的时刻:Agera各个部分的使用介绍,首先要实现Receiver<Bitmap>和Updatable两个接口,并重写对应方法,演示网络请求加载图片。
public class AgeraActivity extends Activity
implements Receiver<Bitmap>, Updatable {
private static final ExecutorService NETWORK_EXECUTOR =
newSingleThreadExecutor();
private static final ExecutorService DECODE_EXECUTOR =
newSingleThreadExecutor();
private static final String BACKGROUND_BASE_URL =
"http://www.gravatar.com/avatar/4df6f4fe5976df17deeea19443d4429d?s=";
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);
// 创建一个repository: 包括一个图片请求。Initially
// 初始值:absent, 配置通过网络获取屏幕大小的图片。
background = repositoryWithInitialValue(Result.<Bitmap>absent())
.observe() // 在这个例子中不需要刷新背景图,也就是不需要被观察者
.onUpdatesPerLoop() // 在这个例子中每次都更新
.getFrom(new Supplier<HttpRequest>() {
@NonNull
@Override
public HttpRequest get() {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int size = Math.max(displayMetrics.heightPixels,
displayMetrics.widthPixels);
return httpGetRequest(BACKGROUND_BASE_URL + size)
.compile();
}
}) // 实现带有显示大小参数的Http请求
.goTo(NETWORK_EXECUTOR) // 设置网络请求线程
.attemptTransform(httpFunction())
.orSkip() // 设置http请求,如果失败,跳过下面流程
.goTo(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));
}
}) // 解码图片, 如果失败返回absent
.onDeactivation(SEND_INTERRUPT) // 中断线程
.compile(); // 创建repository
}
@Override
protected void onResume() {
super.onResume();
// 注册观察者,激活流程
background.addUpdatable(this);
}
@Override
protected void onPause() {
super.onPause();
// 注销观察者,去激活流程
background.removeUpdatable(this);
}
@Override
public void update() {
// repository更新时 调用
// 如果bitmap有效, 发送到下面的accept()方法
background.get().ifSucceededSendTo(this);
}
@Override
public void accept(@NonNull Bitmap background) {
// 设置背景图片
backgroundView.setImageBitmap(background);
}
}
好了,Agera的基础应用已经介绍完了。让我们共同期待Google的正式推出Agera吧。
官方请关注:https://github.com/google/agera
demo下载:点击打开链接