RxAndroid学习笔记<一>

一,什么是Rx

1.Rx的基本介绍:Rx是响应式编程的意思,本质是观察者模式,是以观察者(Observer)和订阅者(Subscriber)为基础的异步响应方式。

(1)缩写:ReactiveX时Reactive Extensions的缩写,一般简写为Rx

(2)定义:Rx = Observables + LINQ + Schedulers.       LINQ---语言集成查询

(3)突破:ReactiveX不仅仅是一个编程接口,它是一种编程思想的突破,它影响了许多其它的程序库和框架以及编程语言。

(4)Rx库支持.Net,JavaScript,C++,常用有RxJava, RxJS,  rx.NET

2.Rx模式以及优点:

<1>使用观察者模式:

(1)创建:Rx可以方便的创建事件流和数据流

(2)组合:Rx使用查询方式的操作符组合和变换数据流

(3)监听:Rx可以订阅任何可观察的数据流并执行操作

<2>简化代码:

(1)函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态

(2)简化代码:Rx的操作符通常可以将复杂的难题简化为很少的几行代码

(3)异步错误处理:传统的try/catch没办法处理异常计算,Rx提供了合适的错误处理机制

(4)轻松使用并发:Rx的Observables和Schedulers让开发者可以摆脱底层的线程同步和各种并发问题

3.Rx提供了什么

(1)Rx提供了一些列的操作符,你可以使用它们来过滤(filter)、选择(select)、变换(transform)、结合(combine)和组合(compose)多个Observable,

这些操作符让执行和复合变得非常高效

(2)我们可以把Observable当做Iterable的推送方式的等价物,使用Iterable,消费者从生产者那拉取数据,线程阻塞直至数据准备好。

使用Observable,在数据准备好时,生产者将数据推送给消费者。数据可以同步或异步的到达,这种方式更灵活。


二,初始RxJava:

1.观察者模式面向的需求:A对象(观察者)对B对象(被观察者)的某种变化高度敏感,需要在B变化的一瞬间作出反应(就是A监看B)

2.RxJava的四个基本概念:Observable(被观察者)、Observer(观察者)、subscrible(订阅)、事件。

(1)Observable和Observer通过subscrible()方法实现订阅关系,从而

Observable可以在需要的时候发出事件来通知Observer.

3.RxJava的基本实现:

(1)创建Observer

Observer即观察者,它决定事件触发的时候有怎样的行为。

RxJava中的Observer接口的实现方式。

(2)创建Observable

Observable即被观察者,它决定什么时候触发事件以及触发怎样的事件。

RxJava使用create()方法来创建一个Observable,并为它定义事件触发规则

(3)Subscribe(订阅)

创建了Observable和Observer之后,再创建subscribe()方法将他们联结起来,整条链子就可以工作了

4,使用例子:

第一个例子:自定义接口实现:

(1)创建观察者接口:定义监听的方法

public interface Watcher {
    //通过update()方法监听到状态的通知
    public void update(String str);
}
(2)创建被观察者接口:提供3个方法,添加观察者,异常观察者,通知提醒所以的观察者

public interface Watched {
    //添加观察者
    public void addWatcher(Watcher watcher);
    //移除观察者
    public void removeWatcher(Watcher watcher);
    //提醒所以的观察者
    public void notifyWatchers(String str);

}
(3)创建实现观察者接口的观察者类:

public class ConcreteWatcher implements Watcher {
    @Override
    public void update(String str) {

        //打印出被观察者的消息的变化
        System.out.println(str);
    }
}
(4)创建实现被观察者接口的被观察者类:用ArrayList来实现多个观察者对象的监听状况

public class ConcreteWatched implements Watched {

    //创建List集合
    private List<Watcher> list = new ArrayList<>();

    @Override
    public void addWatcher(Watcher watcher) {
        //添加观察者对象
        list.add(watcher);

    }

    @Override
    public void removeWatcher(Watcher watcher) {
        //移除观察者对象
        list.remove(watcher);
    }

    @Override
    public void notifyWatchers(String str) {

        //遍历,通知所有观察者被观察对象的消息变化
        for(Watcher watcher : list){
            watcher.update(str);
        }

    }
}
(5)测试类:

public class Test {
    public static void main(String[] args)throws Exception{

        //新建一个被观察者对象:小明
        Watched xiaoming = new ConcreteWatched();

        //新建3个观察者来监听小明的状态
        Watcher watcher1 = new ConcreteWatcher();
        Watcher watcher2 = new ConcreteWatcher();
        Watcher watcher3 = new ConcreteWatcher();

        //把监听器安装在小明身上
        xiaoming.addWatcher(watcher1);
        xiaoming.addWatcher(watcher2);
        xiaoming.addWatcher(watcher3);

        //小明的状改变了
        xiaoming.notifyWatchers("我打算要偷东西了");
        
    }
}
输出如下:

 我打算要偷东西了
 我打算要偷东西了
 我打算要偷东西了

第二个例子:利用Observable和Observer这两个类来实现

import java.util.Observable;
import java.util.Observer;
需要配置builde.gradle(app)环境,添加如下两行(这里先把RxAndroid的一起添加了)

    compile 'io.reactivex:rxandroid:1.1.0' // RxAndroid
    compile 'io.reactivex:rxjava:1.1.0' // 推荐同时加载RxJava
(1)创建SimpleObservable类,继承Observable类:

在里面定义一个数据data,并创建getData()方法,和setData()方法,

再在setData()方法里面设置状态改变监听与通知观察者的方法,如下:

            //设置状态改变
            setChanged();
            //表示状态改变,通知观察者
            notifyObservers();
整体代码:

import java.util.Observable;

/**
 * Created by maiyu on 2017/6/18.
 * 创建一个被观察者类
 */

public class SimpleObservable extends Observable {

    //定义一个数据
    private int data = 0;

    //get方法
    public int getData() {
        return data;
    }

    /**
     * setData方法
     * @param i
     */
    public void setData(int i) {
        if(this.data != i) {
            this.data = i;

            //设置状态改变
            setChanged();
            //表示状态改变,通知观察者
            notifyObservers();
        }
    }
}
(2)创建观察者类:SimpleObserver类,继承Observer:

     初始化构造方法(把被观察者作为参数),重写update方法

在update里实现通知,代码如下:

import java.util.Observer;

/**
 * Created by maiyu on 2017/6/18.
 * 观察者
 */

public class SimpleObserver implements Observer {

    /**
     * 初始化,为被观察者添加观察者对象
     * @param observable
     */
    public SimpleObserver(SimpleObservable observable){
        observable.addObserver(this);

    }

    /**
     * 当被观察者的数据改变时,触发此方法
     * @param o
     * @param object
     */
    @Override
    public void update(Observable o, Object object) {

        //强制转换为SimpleObservable类,并执行它的getData()方法
        System.out.println("data is changed: " + ((SimpleObservable)o).getData());

    }
(3)测试类:

public class Test {
    public static void main(String[] args)throws Exception{

        //创建被观察者对象
        SimpleObservable observable = new SimpleObservable();
        //创建观察者对象,把被观察者当做参数
        SimpleObserver observer = new SimpleObserver(observable);

        observable.setData(1);
        observable.setData(2);
        //此处,因为状态还是2,没有改变,不会通知
        observable.setData(2);
        observable.setData(3);

    }
}
输出结果:

 data is changed: 1
 data is changed: 2
 data is changed: 3
只有在状态改变时才通知,不改变不通知

三,RxAndroid:

在Android编程时,经常会使用后台线程,那么就可以使用这种方式,目前的异步编程方式会导致一些问题,如:

(1).异步任务容易导致内存泄漏

(2)CursorLoaders和ContentProvider的使用经常需要大量的配置数字模板

(3)后台服务长时间运行在后台,不能很快结束操作,会浪费资源

(4)访问网络接口调用返回数据,尤其在使用回调时候,处理数据很麻烦


1.创建观察者

在异步模型中创建观察者:

(1)定义一个方法,它完成某些任务,然后从异步调用中返回一个值,这个方法是观察者的一部分

(2)将这个异步调用本身定义为一个Observable

(3)观察者通过订阅(Subscribe)操作关联到哪个Observable

(4)继续你的业务逻辑,等方法返回时,Observable会发射结果,观察者的方法会开始处理结果或者结果集

2.观察者回调方法:onNext, onError , onComplete

(1)onNext(T item):Observable调用这个方法发射数据,方法的参数就是Observable发射的数据,这个方法可能会被多次调用,取决于我们的实现

(2)onError(Exception ex)

当Observable遇到错误或者无法返回期望的数据时会调用这个方法,这个调用会终止Observable,后续不会再调用onNext和onCompleted,

onError方法的参数就是抛出的异常

(3)onComplete

正常终止,如果没有遇到错误,Observable在最后一次调用onNext之后调用此方法

3.创建操作Create:

(1)使用一个函数从头开始参加一个Observable:

Create{onNext    ;  onNext   ; onComplete}

注意:可在传递给create方法的函数中检查观察者的isUnsubscribed状态,以便在没有观察者的时候,让你的Observable停止发射数据或做昂贵的运算。

4.例子如下:

创建类:RxUtils,用于存放后面没种实现方式的方法

public class RxUtils {

    private static final String TAG = RxUtils.class.getSimpleName();
<1>第一例子:使用Observable.create()方法来创建:

(1)创建Observable对象,在create方法里面传入参数new Observable.OnSubscribe()对象,

然后利用onNext设置信息,最后调用onComplete()方法,如下:

        //使用Observable.create方法来创建
        Observable<String > observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("hello");
                subscriber.onNext("good");
                subscriber.onNext(downLoadJson());
                subscriber.onNext("约吗");

                //调用onCompleted()方法来完成
                subscriber.onCompleted();
            }
        });
(2)创建Subscriber对象,重写onError,onComplete,onNext方法:

代码如下:

        //创建Subscriber对象,这里传入字符串类型,因为什么我们是发送字符串
        Subscriber<String> showsub = new Subscriber<String>() {
            @Override
            public void onCompleted() {
                Log.i(TAG , "onCompleted");
            }

            @Override
            public void onError(Throwable e) {

                Log.i(TAG , "onError:"+ e.toString());
            }

            @Override
            public void onNext(String s) {

                Log.i(TAG , "onNext: " + s);
            }
        };
    /**
     * 定义下载方法
     * @return
     */
    private static String downLoadJson() {
        return "json_data";
    }

(3)调用Observable对象的subscribe关联Subscriber对象:

        /**
         * 关联被观察者
         */
        observable.subscribe(showsub);
(4)在Activity中为某个按钮设置监听:

    public void btnOnClick(View view){
        RxUtils.createObservable();
    }
(5)输出结果如下:

06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: hello
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: good
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: json_data
06-20 01:30:46.313 6162-6162/? I/RxUtils: onNext: 约吗
06-20 01:30:46.313 6162-6162/? I/RxUtils: onCompleted

<2>第二种方法:也是利用create方法,只是不用创建Observable和Subscriber对象,而是直接实现,如下:打印整数1到10

    public static void createObservable2(){

        Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                //如果没有解除关联
                if(!subscriber.isUnsubscribed()){

                    for(int i = 0 ; i < 10 ; i++){
                        subscriber.onNext(i);
                    }
                    subscriber.onCompleted();
                }

            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.i(TAG , "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG , "e: " + e.toString());
            }

            @Override
            public void onNext(Integer integer) {
                Log.i(TAG , "onNext: " +integer);
            }
        });

    }
Activity中按钮监听:

    public void btnOnClick2(View view){
        RxUtils.createObservable2();
    }
输出结果:

06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 0
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 1
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 2
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 3
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 4
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 5
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 6
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 7
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 8
06-20 01:36:37.593 6162-6162/? I/RxUtils: onNext: 9
06-20 01:36:37.593 6162-6162/? I/RxUtils: onCompleted

<3>第3种方法:from()方法,定义数组

    /**
     * Observable.from()方法
     * 使用在被观察者,返回的一般都是数据类型
     */
    public static void from(){

        Integer[] items = {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9};
        Observable observable = Observable.from(items);

        observable.subscribe(new Action1() {
            @Override
            public void call(Object o) {

                Log.i(TAG , o.toString());
            }
        });

    }
输出:

06-20 02:01:43.081 6162-6162/? I/RxUtils: 1
06-20 02:01:43.081 6162-6162/? I/RxUtils: 2
06-20 02:01:43.081 6162-6162/? I/RxUtils: 3
06-20 02:01:43.081 6162-6162/? I/RxUtils: 4
06-20 02:01:43.081 6162-6162/? I/RxUtils: 5
06-20 02:01:43.081 6162-6162/? I/RxUtils: 6
06-20 02:01:43.081 6162-6162/? I/RxUtils: 7
06-20 02:01:43.081 6162-6162/? I/RxUtils: 8
06-20 02:01:43.081 6162-6162/? I/RxUtils: 9
                                          
                                          --------- beginning of /dev/log/system

<4>第4种:Interval指定时间间隔发送数据:

    /**
     * interval指定某一时刻进行数据发送:定时器
     */
    public static void interval(){

        //每隔1秒发送一次数据
        Observable observable = Observable.interval(1 , 1 , TimeUnit.SECONDS);
        observable.subscribe(new Action1() {
            @Override
            public void call(Object o) {
                Log.i(TAG , o.toString());
            }
        });

    }

输出结果:发现每隔1秒,后台就打印一个数据,,截取部分如下:

06-20 02:04:28.997 25326-25438/? I/RxUtils: 0
06-20 02:04:29.997 25326-25438/? I/RxUtils: 1
06-20 02:04:30.997 25326-25438/? I/RxUtils: 2
06-20 02:04:32.001 25326-25438/? I/RxUtils: 3
06-20 02:04:32.997 25326-25438/? I/RxUtils: 4
...

<5>第5种:just来实现范围数据,参数为多个数组对象,如:

    /**
     * 范围数据:如下面依次输出两个数组的元素
     */
    public static void just(){

        //定义两个数组
        Integer[] items1 = {1 , 3 , 5 , 7 , 9};
        Integer[] items2 = {2 , 4 , 6 , 8 , 10};

        //调用Observable.just(数组1,数组2,.....数组10);
        Observable observable   =   Observable.just(items1 , items2);

        //在这里设置Subscriber的类型为Integer[]:对应上面的Integer类型的数组
        observable.subscribe(new Subscriber<Integer[]>() {
            @Override
            public void onCompleted() {
                Log.i(TAG , "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG , "onError: " + e.getMessage());
            }

            @Override
            public void onNext(Integer[] o) {
                for(Integer i : o)
                    Log.d(TAG , "onNext : " +i);
            }
        });

    }
输出结果:依次输出两个数组的数据

06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 1
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 3
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 5
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 7
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 9
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 2
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 4
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 6
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 8
06-20 02:07:00.337 25643-25643/? D/RxUtils: onNext : 10
06-20 02:07:00.337 25643-25643/? I/RxUtils: onCompleted
<6>第6种:利用range来实现从指定初始位置和个数的范围,如:

    /**
     * range方法:定义开始下标与个数
     */
    public static void range(){

        //利用Observable.range(开始下标,个数);
        Observable observable   =   Observable.range(3 , 5);

        //传入Action1的参数类型Integer
        observable.subscribe(new Action1<Integer>() {

            @Override
            public void call(Integer integer) {
                Log.d(TAG , "call : " + integer);
            }
        });
    }
输出结果:

06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 3
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 4
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 5
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 6
06-20 02:08:38.109 25643-25643/? D/RxUtils: call : 7
                                            
                                            --------- beginning of /dev/log/system
<7>第7种:利用filter来实现某些过滤信息:

    /**
     * Observable.filter()方法:用于过滤某些东东
     */
    public static void filter(){

        //创建一个数组
        Integer[] items = {1 , 2 , 3 , 4 , 5 , 6};
        //调用from添加
        Observable observable = Observable.from(items);
        //添加过滤器,传入<Integer,Boolean>参数:过滤小于等于3的数字
        observable.filter(new Func1<Integer , Boolean>() {

            @Override
            public Boolean call(Integer integer) {
                return integer > 3;
            }
        })
                //设置订阅者是如何执行的:Schedulers.io---通过网络获取数据
                .observeOn(Schedulers.io())
                .subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.d(TAG , "onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG , "onError : " + e.getMessage());
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG , "onNext : " + integer);
            }

        });
    }
结果如下:

06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 4
06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 5
06-20 02:13:52.561 26628-26661/? D/RxUtils: onNext : 6
06-20 02:13:52.561 26628-26661/? D/RxUtils: onCompleted


四,RxAndroid应用场景

1.替代AsyncTask完成下载操作

2.结合OkHttp完成网络访问操作、包括下载文件、提交form表单数据

3.结合ListView、GridView使用完成对图文混排操作

4.结合OkHttp网络访问框架使用

5.RxAndroid编程思路的总结


1.替代AsyncTask完成下载操作:如下载一直图片

(1)在Activity中:

 * 在实际开发中Activity充当的角色太多了:
 * 1.UI主线程负责绘制UI
 * 2.开启子线程获取网络数据
 * 3.赋值到控件中
 * 4.判断逻辑等等

而下载图片常用方法:

/**
 * 下载张图片:
 * 1.AsyncTask
 * 2.Handler机制
 * 3.发现有更好的即观察者模式
 */
如第1种:那么必须创建类继承AsyncTask<String , 参数,byte[]>等

或者自己封装:

public class DownLoadUtils {

    /**
     * 传统模式,
     *
     * @param path
     * @return
     */
    public static byte[] downloadImg(String path, CallBack callBack) {
        //在这里定义异步任务

        return null;

    }

    interface CallBack {
        void callback(byte[] data);
    }

}

但是发现这些太繁琐或是消耗资源多, 于是采用第3种:

(2)创建工具类:

主要有如下几个知识点:

------定义并在构造方法里创建OkHttpClient

记得在build.gradle添加OkhttpClient的依赖

    compile 'com.squareup.okhttp:okhttp:2.7.2'
------使用Observable创建下载方法,参数为path,

public class DownLoadUtils {

    //定义OkHttpClient
    private OkHttpClient okHttpClient ;

    /**
     * 构造函数:实例化OkHttpClient对象
     */
    public DownLoadUtils(){
        okHttpClient = new OkHttpClient();
    }


    /**
     * 创建观察者模式的下载方法,这里
     * @param path      -----传入地址参数
     * @return          ------返回btye[]数组
     */
    public Observable<byte[]> downloadImg(final String path){

        //使用create()方法
        return Observable.create(new Observable.OnSubscribe<byte[]>() {
            @Override
            public void call(final Subscriber<? super byte[]> subscriber) {

                //判断是否已经绑定订阅
                if(!subscriber.isUnsubscribed()){

                    //使用OkhttpClient访问网络步骤
                    //创建Request对象,调用.url()传入地址,build()完成
                    Request request = new Request.Builder().url(path).build();
                    //调用okttpClient.newCall(Request对象).enqueue()执行异步get请求
                    okHttpClient.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Request request, IOException e) {
                            //执行subscriber.onError()方法
                            subscriber.onError(e);
                        }

                        /**
                         * 请求成功
                         * @param response
                         * @throws IOException
                         */
                        @Override
                        public void onResponse(Response response) throws IOException {

                            //判断返回结果是否成功
                            if(response.isSuccessful()){
                                //获取返回的byte[]数组
                                byte[] data = response.body().bytes();
                                //判空
                                if(data != null){
                                    //发射数据
                                    subscriber.onNext(data);
                                }
                            }
                            //完成
                            subscriber.onCompleted();
                        }
                    });
                }
            }
        });

    }


}
在Activity中:

初始化DownLoad类:

utils = new DownLoadUtils();
为按钮设置监听,在监听里面执行代码如下:

                //下载图片------设置订阅执行方式(通过网络获取数据)-----设置主线程显示
                utils.downloadImg(imgPath).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Subscriber<byte[]>() {
                            @Override
                            public void onCompleted() {
                                Log.i(TAG , "onCompleted");//对话框取消
                            }

                            @Override
                            public void onError(Throwable e) {
                                Log.i(TAG , "onError: " + e);
                            }

                            @Override
                            public void onNext(byte[] bytes) {

                                //显示图片,这里没有对图片进行压缩等处理
                                Bitmap bitmap = BitmapFactory.decodeByteArray(bytes , 0 , bytes.length);
                                mImg.setImageBitmap(bitmap);
                            }
                        });

结果:显示一张图片:

如传入地址:

 private String imgPath = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1497953788142&di=370d893f7390ea12dc770083b171c1f2&imgtype=0&src=http%3A%2F%2Fxke8.com%2Fuploads%2Fallimg%2Fc150921%2F1442O51G4A0-1I13.jpg";
有点长,不过结果辣眼睛,瞬间秒杀你的困意:





2.利用OkhtttpClient实现用户登录:

主要代码如下:

工具类:

/**
 * Created by maiyu on 2017/6/20.
 * 登录类
 */

public class LoginUtils {
    //定义OkHttpClent对象
    private OkHttpClient okHttpClient ;
    public LoginUtils(){
        okHttpClient = new OkHttpClient();
    }

    /**
     * 登录实现
     * @param url
     * @param params
     * @return  String
     */
    public Observable<String> login(final String url , final Map<String , String> params){

        return  Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(final Subscriber<? super String> subscriber) {

                //判断是否已经绑定
                if(!subscriber.isUnsubscribed()){

                    //创建FormEncodingBuilder对象
                    FormEncodingBuilder builder = new FormEncodingBuilder();

                    //添加参数
                    if(params != null && !params.isEmpty()){
                        for(Map.Entry<String , String> entry : params.entrySet()){

                            builder.add(entry.getKey() , entry.getValue());
                        }
                    }
                    //创建RequestBody对象
                    RequestBody body = builder.build();

                    //创建Request对象
                     Request request = new Request.Builder().url(url).post(body).build();

                    okHttpClient.newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(Request request, IOException e) {
                            subscriber.onError(e);
                        }

                        @Override
                        public void onResponse(Response response) throws IOException {

                            if(response.isSuccessful()){
                                //订阅
                                subscriber.onNext(response.body().string());
                            }
                            subscriber.onCompleted();
                        }
                    });
                }



            }
        });


    }
}
登录按钮监听实现:

    public void toLogin(){


        Map<String , String> params = new HashMap<String , String>();
        params.put("username" , "获取用户名");
        params.put("password" , "获取密码");

        loginUtils.login(loginUrl , params).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG , "onCompleted");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG , "onError : " + e);
                    }

                    @Override
                    public void onNext(String s) {

                        //跳转...
                        Intent intent = new Intent();
                        startActivity(intent);
                    }
                });
        
    }


附注代码下载地址: 代码下载地址





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Kotlin 的协程来实现这个转换过程。您可以使用 `flow.collect()` 将数据从 `Flow<List<NoteContentEntity>>` 收集到可变的状态中,并使用 `mutableStateOf()` 函数来创建可变状态变量。下面是一个示例代码: ```kotlin import androidx.compose.runtime.mutableStateOf import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch fun convertFlowToList(flow: Flow<List<NoteContentEntity>>): MutableState<List<NoteContentEntity>> { val listState = mutableStateOf<List<NoteContentEntity>>(emptyList()) launch { flow.collect { listState.value = it } } return listState } ``` 在上面的代码中,我们首先创建了一个可变状态变量 `listState` 并将其初始化为空列表。然后我们启动了一个协程来收集数据库查询返回的流,并将其更新到 `listState` 变量中。最后我们返回 `listState` 变量。 您可以在 Android 中使用这个函数来将查询返回的流转换为可变状态变量,并在 Compose 组件中使用它来显示数据。下面是一个使用示例: ```kotlin val noteListState = convertFlowToList(noteDao.getAllNoteContent()) LazyColumn { items(noteListState.value) { noteContent -> NoteListItem(noteContent) } } ``` 在上面的代码中,我们首先调用 `convertFlowToList()` 函数将查询返回的流转换为可变状态变量 `noteListState`。然后我们使用 `LazyColumn` 组件显示查询返回的结果,并使用 `NoteListItem` 组件来显示每个笔记内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值