RxJava2 Flowable解决异步回调

需求:

1项目中有个需求,假设有N个数据,格式为8位纯数字字符串("00015756"),

2需要把N个数据按照尾号0-9分组排好。尾号为“0”的一组,尾号为“1”的一组...最多10组
3在每一组之前添加新唤醒数据帧”AAAAAAAA“,在结尾添加新睡眠数据帧“BBBBBBBB”
4按照0-9分好组的顺序,蓝牙把这些数据发送给硬件
5每组中唤醒帧”AAAAAAAA“发完等待11s,(11s内硬件不回复任何内容),后发送数据,
 发送完数据后蓝牙会立刻回复,收到数据后立即发送下一条数据(不等待3s超时),
 如果超过3秒未回复,就要发送下一个数据。
 最后发本组睡眠帧“BBBBBBBBB”,等待3s(3s内硬件不回复任何内容).循环剩下的组


想了很久,这个逻辑是无法用rxjava一行代码写下来的,因为处理的是两个数据流。
(蓝牙发送数据,蓝牙接收数据)

各位宝宝先看看本宝宝最后完美实现的结果


发送唤醒帧后间隔11s发数据,发送睡眠帧后间隔3s发数据,发送数据帧数据间隔3s,

如果收到回复数据直接发下一数据

实现代码贴上:


 
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button button;
    Context context;
    private  ArrayList<String> dataList;
    static Subscription subscription;
    static Disposable disposable;
    static String currentData;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        setContentView(R.layout.activity_main);
        initView();
        generateData();
        sortArray();
    }

    /**
     *    生成原始数据
     */
    public  void generateData() {
        dataList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            dataList.add("000000" + i);
        }
    }

    /**
     * 数据排序  此方法写的太丑,可以跳过不看
     * 1需要把N个数据按照尾号0-9分组排好。尾号为“0”的一组,尾号为“1”的一组...最多10组
     * 2在每一组之前添加新数据”AAAAAAAA“,在结尾添加新数据“BBBBBBBB”
     * 例如: AAAAAAAA, 00000020, 00000010, 0000000, BBBBBBBB,
     */
    public  void sortArray() {
        ArrayList<String> list0 = new ArrayList<>();
        list0.add("AAAAAAAA");
        list0.add("BBBBBBBB");
        ArrayList<String> list1 = (ArrayList<String>) list0.clone();
        ArrayList<String> list2 = (ArrayList<String>) list0.clone();
        ArrayList<String> list3 = (ArrayList<String>) list0.clone();
        ArrayList<String> list4 = (ArrayList<String>) list0.clone();
        ArrayList<String> list5 = (ArrayList<String>) list0.clone();
        ArrayList<String> list6 = (ArrayList<String>) list0.clone();
        ArrayList<String> list7 = (ArrayList<String>) list0.clone();
        ArrayList<String> list8 = (ArrayList<String>) list0.clone();
        ArrayList<String> list9 = (ArrayList<String>) list0.clone();
        for (String ss : dataList) {
            if (ss.endsWith("0")) {
                list0.add(1, ss);
            } else if (ss.endsWith("1")) {
                list1.add(1, ss);
            } else if (ss.endsWith("2")) {
                list2.add(1, ss);
            } else if (ss.endsWith("3")) {
                list3.add(1, ss);
            } else if (ss.endsWith("4")) {
                list4.add(1, ss);
            } else if (ss.endsWith("5")) {
                list5.add(1, ss);
            } else if (ss.endsWith("6")) {
                list6.add(1, ss);
            } else if (ss.endsWith("7")) {
                list7.add(1, ss);
            } else if (ss.endsWith("8")) {
                list8.add(1, ss);
            } else if (ss.endsWith("9")) {
                list9.add(1, ss);
            }
        }
        dataList.clear();
        dataList.addAll(list0);
        dataList.addAll(list1);
        dataList.addAll(list2);
        dataList.addAll(list3);
        dataList.addAll(list4);
        dataList.addAll(list5);
        dataList.addAll(list6);
        dataList.addAll(list7);
        dataList.addAll(list8);
        dataList.addAll(list9);
        System.out.println(dataList);
    }


    private void initView() {
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                test(dataList);
                break;
        }
    }

    //处理业务逻辑的主要代码 
    private void test(List<String> list) {
        Flowable.fromIterable(list)
                .onBackpressureBuffer()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new MySubscriber());
    }


    /**
     * 倒计时3秒,用于蓝牙超时未反回时请求下一条数据
     * @param time 延时时间 单位 :秒
     */
    public static void countDown(final int time) {
        //取消当前延时
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
        //开始下个延时
        Observable.timer(time, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onNext(Long value) {
                        requestNext();
                    }

                    @Override
                    public void onError(Throwable e) {}

                    @Override
                    public void onComplete() {}
                });
    }

    /**
     * 请求发送下一个数据
     */
    public static void requestNext() {
        if (subscription != null) {
            subscription.request(1);
        }
    }


    /**
     * 模拟蓝牙收到数据后并解析成功后的回调
     * 收到数据后取消当前3s等待超时,并请求下一条数据
     */
    public static void onBluetoothReceive() {
        Observable.intervalRange(0, 30, 1300, 1800, TimeUnit.MILLISECONDS)
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        //假设是偶数的蓝牙数据都收到了硬件的回复
                        if (aLong % 2 == 0 && currentData.matches("\\d+")) {
                            Log.e("蓝牙收到数据", "时间:" + String.format("%tT%n", new Date()));
                            requestNext();
                            countDown(3);
                        }
                    }
                });
    }


    static class MySubscriber implements Subscriber<String> {
        @Override
        public void onSubscribe(Subscription s) {
            subscription = s;
            s.request(1);
            onBluetoothReceive();
        }

        @Override
        public void onNext(String o) {
            currentData = o;
            Log.d("蓝牙发送数据", o+"时间:" + String.format("%tT%n", new Date()));
            //如果发送数据延迟3s
            if (o.matches("\\d+")) {
                countDown(3);
            } else {
                //如果发送唤醒延迟11s (包含A)
                if (o.contains("A"))
                    countDown(11);
                else
                    //如果发送睡眠延迟3s
                    countDown(3);
            }
        }

        @Override
        public void onError(Throwable t) {}

        @Override
        public void onComplete() {}
    }




}

总结:

整个代码逻辑思路:
1:把dataList发射出来,在MySubscriber中的onSubscribe中请求数据,并假装开启蓝牙数据接收回调
2:在onNext收到数据执行后,调用countDown开始超时的延时,如果收到数据,取消当前延时,否则在countDown内又请求数据
3:核心方法 subscription.requset(long n) 要求上游给下游发射多少个数据,这样可以主动控制
数据下发的速度。
4:Flowable 主要是解决背压问题的,但我用subscription.requset(long n)来处理异步回调,也不矛盾
当我把dataList添加300个元素时也没有出现什么异常情况,这其实和数据数量没啥关系,和处理速度有
关。我是参考:https://www.jianshu.com/p/ff8167c1d191


猜你喜欢

转载自blog.csdn.net/qq_35599978/article/details/80724017