JamesP1949 2017-04-01 08:38 采纳率: 0%
浏览 1567

Android:RxJava数据流控制 背压策略使用

最近在开发一款人脸比对的项目,使用RxJava1.x实现的比对逻辑
场景如下:
定时抓取摄像头预览图片进行比对 符合条件时使用 takeUntil操作符停止发射数据 然后使用timer过一定时间后重启比对 但是每次重启后都会获取上次最后一张图片去比对 不晓得原因是什么 在每次重启前都清空了订阅事件的
直接上代码:

  /**
     * 比对程序
     */
    @Override
    public void detect() {
        // 1. 过滤 数据库中的人脸数量不为空 若为空不能有效比对 直接过滤掉
        if (mPersonList.isEmpty()) return;
        mSubscription = Observable
                .interval(0, 500, TimeUnit.MILLISECONDS)
                .onBackpressureDrop() // 使用背压策略:总是接收最新的
                // 2. 获得预览图片
                .map(new Func1<Long, Bitmap>() {
                    @Override
                    public Bitmap call(Long aLong) {
                        KLog.e("aLong:" + aLong);
                        return mView.takePhoto();
                    }
                })
                // 3. 过滤掉为null的图片
                .filter(new Func1<Bitmap, Boolean>() {
                    @Override
                    public Boolean call(Bitmap bitmap) {
                        return bitmap != null;
                    }
                })
                // 4. 将图片保存在对象DetectSuccessInfo
                .flatMap(new Func1<Bitmap, Observable<DetectSuccessInfo>>() {
                    @Override
                    public Observable<DetectSuccessInfo> call(Bitmap bitmap) {
                        DetectSuccessInfo detectSuccessInfo = new DetectSuccessInfo();
                        detectSuccessInfo.setDetectBitmap(bitmap);
                        return Observable.just(detectSuccessInfo);
                    }
                })
                .observeOn(Schedulers.io()) // 运行在子线程
                // 5. 提取图片中的人脸特征 无人脸时特征值为----""
                .flatMap(new Func1<DetectSuccessInfo, Observable<DetectSuccessInfo>>() {
                    @Override
                    public Observable<DetectSuccessInfo> call(DetectSuccessInfo
                                                                      successInfo) {
                        String[] feature_ = FeatureUtils.extractFeature_(successInfo
                                .getDetectBitmap());
                        successInfo.setRect(feature_[0]);
                        successInfo.setFeature(feature_[1]);
                        return Observable.just(successInfo);
                    }
                })
                // 6. 过滤条件:图片提取的人脸特征不为空
                .filter(new Func1<DetectSuccessInfo, Boolean>() {
                    @Override
                    public Boolean call(DetectSuccessInfo successInfo) {
                        return !TextUtils.isEmpty(successInfo.getFeature());
                    }
                })
                // 7. 标定人脸相框
                .doOnEach(new Action1<Notification<? super DetectSuccessInfo>>() {
                    @Override
                    public void call(Notification<? super DetectSuccessInfo> notification) {
                        DetectSuccessInfo successInfo = (DetectSuccessInfo) notification
                                .getValue();
                        Bitmap bitmap = successInfo.getDetectBitmap();
                        int[] result = StringUtils.split2Int(successInfo.getRect());
                        mView.convertCoordinate(result[0], result[1], result[2],
                                result[3], bitmap.getWidth(), bitmap.getHeight());
                    }
                })
                // 8. 过滤条件:和数据库查询的人脸集合中的每一个人脸进行比对 选取最大值且有匹配成功的对象
                .map(new Func1<DetectSuccessInfo, DetectSuccessInfo>() {
                    @Override
                    public DetectSuccessInfo call(DetectSuccessInfo successInfo) {
                        float[] fea = StringUtils.split2Float(successInfo.getFeature());
                        List<Object> objects = FeatureUtils.matchWithDbData(mPersonList,
                                fea);
                        if (!objects.isEmpty()) {
                            successInfo.setScore((Float) objects.get(0));
                            successInfo.setPerson((Person) objects.get(1));
                            successInfo.setSuc_time(System.currentTimeMillis());
                        }
                        return successInfo;
                    }
                })
                // 9. 过滤 只有分数大于阈值的才可以继续进行 小于则继续下一次循环开始抓取图片
                .filter(new Func1<DetectSuccessInfo, Boolean>() {
                    @Override
                    public Boolean call(DetectSuccessInfo successInfo) {
                        KLog.e("filter:" + successInfo.getScore());
                        return successInfo.getScore() >= 50;
                    }
                })
                // 10. 判断匹配成功的唯一标准DetectSuccessInfo score属性且大于阈值
                // 成功则停止发送数据
                .takeUntil(new Func1<DetectSuccessInfo, Boolean>() {
                    @Override
                    public Boolean call(DetectSuccessInfo successInfo) {
                        KLog.e("takeUntil:" + successInfo.getScore());
                        return successInfo.getScore() >= 50;
                    }
                })
                // 11. 每次匹配成功 开启子线程入库
                .doOnNext(new Action1<DetectSuccessInfo>() {
                    @Override
                    public void call(final DetectSuccessInfo successInfo) {
                        Schedulers.io().createWorker().schedule(new Action0() {
                            @Override
                            public void call() {
                                DetectRecord record = new DetectRecord();
                                record.setDetectScore(String.valueOf(successInfo.getScore
                                        ()));
                                record.setDetectTime(successInfo.getSuc_time());
                                record.setPerson_id(successInfo.getPerson().get_id());
                                record.setDetectImage(ImageUtils.BitmapToBytes(successInfo
                                        .getDetectBitmap()));
                                mDaoManager.insertRecord(record);
                                KLog.e("保存比对数据入库");
                            }
                        });
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<DetectSuccessInfo>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        KLog.e("Error:" + e.getMessage());
                    }

                    @Override
                    public void onNext(DetectSuccessInfo successInfo) {
                        // 12. 匹配成功刷新页面
                        mView.me_succeed(successInfo);
                    }

                    @Override
                    public void onStart() {
                        super.onStart();
                        mView.resetUI();
                    }
                });
        KLog.e("detect----subscription:" + mSubscription);
        addSubscribe(mSubscription);
    }

重启代码:

  /**
     * 比对成功后延时1.5秒重新开始匹配
     */
    @Override
    public void reStart() {
        Subscription subscription = Observable.timer(1500, TimeUnit.MILLISECONDS)
                .compose(SchedulersCompat.<Long>applyIoSchedulers())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        cleanSubscribe(mSubscription);
                        // 重新开始匹配
                        mView.resetUI();
                        detect();
                    }
                });
        addSubscribe(subscription);
    }

在线求大神指点!!!

  • 写回答

1条回答 默认 最新

  • 开发者-钟大田 2017-04-01 13:18
    关注

    看代码有点恶心呀。不知道为什么我不喜欢。Builder模式的代码,这么泛滥。

    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题