节流方法调用RxJava

时间:2016-03-06 22:22:06

标签: java android rx-java accessibilityservice

我想使用RxJava来限制AccessibilityEventandroid.accessibilityservice.AccessibilityService特别是TYPE_VIEW_TEXT_CHANGED event获得的数量。

每次用户在EditText窗口小部件中显示任何内容时,它都会被触发。不过,我尝试使用debouncethrottleLastthrottleFirst甚至buffer。但是,如果我还没有完成我想要发出的所有事件,我不确定应该如何使用它们。

public class AccessibilityService extends android.accessibilityservice.AccessibilityService {

    @Inject
    AccessibilityServiceController accessibilityServiceController;

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Timber.d("AccessibilityEvent was received: " + event.toString());
        //Throttle so I only get the last event in XXX milliseconds.
        accessibilityServiceController.evaluateEvent(event);
    }

    @Override
    public void onInterrupt() {
        Timber.e("Service was interrupted! ");
    }
} 

我想要与此debounce小部件上使用的EditText类似的内容 Kaushik Gopal's DebounceSearchEmitterFragment.java

所以我的输出可以是:

[这是]

[这是一个]

[这是一个测试]

而不是:

[T]

[th]

[thi]

[this]

...

提前致谢!

2 个答案:

答案 0 :(得分:1)

我会做以下事情:

  • 创建一个设置“辅助功能监听器”
  • 的observable
  • 此侦听器可以启动RxJava事件流
  • 订阅流,并让服务控制器在适当的时间评估该事件

重新设计某些内容以使其具有反应性的关键是确保代码中的所有内容都成为某种触发器。如果您需要流中的某些逻辑,则回调不会做太多。

以下是一个例子:

AccessibilityServiceController accessibilityServiceController;
Action1<AccessibilityEvent> accessibilityEventListener;

AccessibilityService() {
    accessibilityServiceController = new AccessibilityServiceController();
    Observable.create(new Observable.OnSubscribe<AccessibilityEvent>() {
        @Override
        public void call(final Subscriber<? super AccessibilityEvent> subscriber) {
            accessibilityEventListener = new Action1<AccessibilityEvent>() {
                @Override
                public void call(AccessibilityEvent accessibilityEvent) {
                    subscriber.onNext(accessibilityEvent);
                }
            };
        }
    })
    .debounce(500, TimeUnit.MILLISECONDS) // <-----
    .subscribe(new Action1<AccessibilityEvent>() {
        @Override
        public void call(AccessibilityEvent accessibilityEvent) {
            accessibilityServiceController.evaluateEvent(accessibilityEvent);
        }
    });

}

private void setAccessibilityEventListener(Action1<AccessibilityEvent> listener) {
    accessibilityEventListener = listener;
}

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    // This will be throttled every 500 Milliseconds
    accessibilityEventListener.call(event);
}

你可能不想把这些东西放在构造函数中,但你明白了。 Observable构建到侦听器。我还建议保留对Subscription的引用,因为为了防止内存泄漏而取消订阅非常重要!

答案 1 :(得分:0)

行。

我发现有一些PublishSubject / Subject

我基本上可以在创建Observable之后将onNext发布为某种setter,这就是我所追求的。

public class AccessibilityService extends android.accessibilityservice.AccessibilityService {
    private final PublishSubject<AccessibilityEvent> accessibilityEventPublishSubject = PublishSubject.create();

    public AccessibilityServiceControllerImpl() {
        accessibilityEventPublishSubject
                .debounce(400, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<AccessibilityEvent>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(AccessibilityEvent accessibilityEvent) {
                        Log.d(TAG, accessibilityEvent.toString());
                    }
                });
    }

    @Override
    public void evaluateEvent(final AccessibilityEvent accessibilityEvent) {
        int type = accessibilityEvent.getEventType();
        switch (type) {
            case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
                Timber.d("Event received in controller: " + accessibilityEvent.toString());
                accessibilityEventPublishSubject.onNext(accessibilityEvent);
                break;
            default:
                break;
        }
    }
}

这就是这个问题的答案。但是,我在executeMessage android.accessibilityservice.AccessibilityService内被@Override public void executeMessage(Message message) { switch (message.what) { case DO_ON_ACCESSIBILITY_EVENT: { AccessibilityEvent event = (AccessibilityEvent) message.obj; if (event != null) { AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event); mCallback.onAccessibilityEvent(event); try { //EVENT IS RECYCLED BEFORE THE ONNEXT IS CALLED IN MY PUBLISHSUBJECT event.recycle(); } catch (IllegalStateException ise) { } } } return; ... bla bla 回收时面对空物品。

Unit

但我想这是值得的另一个问题。