响应式编程越来越符合现在的数据为核心的开发思路。所以,在去年,响应式也越来越火,从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~

posted on 2016-04-26 23:25  Fishbonell  阅读(1070)  评论(0编辑  收藏  举报