响应式编程越来越符合现在的数据为核心的开发思路。所以,在去年,响应式也越来越火,从RxJava到React(支持了响应式)。如今,为了满足更多开发者的需求,Google也推出了自己的响应式框架——Agera。
我之前从来没有进行过相关的开发,Agera算是第一次接触响应式开发,虽说它是一种新的开发思路。但我更习惯于,从它解决了什么问题,开始说起。
其实在Android开发中,大家常常会面对非UI线程更新UI的问题。这个问题在百度上解答已经非常多了。其根本就是使用Handler,传递消息。但是Handler这个类的使用,不那么美观,结构不好看,还容易内存泄露。因此,各种框架对其进行了封装。从原生框架中的AsyncTask到后面EventBus,到如今的Agera都是对Handler传递消息这件事,进行了各种封装,让它更加的优雅。由于刚接触这个框架,原理暂时无力细说。在此先记录一下它的用法。
Agera其实就是个观察者模式。分为两部分,数据源和观察者。当然,一个类也可以同时拥有这两种身份。
先看数据源的demo代码:
import com.google.android.agera.BaseObservable;/** * Created by longsiyang on 2016/4/20. */ public class BaseBean extends BaseObservable { private String content = ""; public String getContent() { return content; } public void setContent(String content) { this.content = content; update(); } public void update(){ new Thread(new Runnable() { @Override public void run() { content += " after other thread"; dispatchUpdate(); } }).start(); } }
这个类继承了BaseObservable,成为了Agera的数据源。我自己为这个数据写了get、set、update方法。
我们可以注意到,update方法代码,是在一个新线程中执行的。在执行完成后,会调用dispatchUpdate()。这个方法是从BaseObservable继承下来的,功能就是通知这个数据源的所有观察者,执行update()方法。
我们点进去看源码会发现:
void dispatchUpdate() { handler.obtainMessage(MSG_UPDATE, this).sendToTarget(); }
以上就是数据源相关的。
接下来,我们看看如何成为观察者。本例中,让一个Activity成为观察者。
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import android.widget.TextView; import com.google.android.agera.Updatable; public class MainActivity extends AppCompatActivity implements Updatable { BaseBean baseBean; EditText editText; TextView textView1 , textView2 , textView3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView1 = (TextView) findViewById(R.id.test_tv_id1); textView2 = (TextView) findViewById(R.id.test_tv_id2); textView3 = (TextView) findViewById(R.id.test_tv_id3); baseBean = new BaseBean(); editText = (EditText) findViewById(R.id.test_eidt_id); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (baseBean != null){ baseBean.setContent(s.toString()); } } @Override public void afterTextChanged(Editable s) { } }); } @Override protected void onResume() { super.onResume(); baseBean.addUpdatable(this); } @Override protected void onPause() { super.onPause(); baseBean.removeUpdatable(this); } @Override public void update() { textView1.setText(baseBean.getContent()); textView2.setText(baseBean.getContent()); textView3.setText(baseBean.getContent()); } }
这个Activity中,我监听了Edittext的内容变化。
在onResume中让观察者加入数据源,在onPause中让观察者移出数据源。并在Edittext内容变化时,改变数据源内容。改变内容时,由于调用了数据源的dispatchUpdate()方法,会使观察者调用update()方法。此时,Activity中的update()方法就会调用,更新textview1、textview2、textview3中的内容。
通过这些简洁的代码,我们就完成了一个结构优雅的,非UI线程更新UI。
Done~