我想使用RxJava
来限制AccessibilityEvent
从android.accessibilityservice.AccessibilityService
特别是TYPE_VIEW_TEXT_CHANGED event获得的数量。
每次用户在EditText
窗口小部件中显示任何内容时,它都会被触发。不过,我尝试使用debounce
,throttleLast
,throttleFirst
甚至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]
...
提前致谢!
答案 0 :(得分:1)
我会做以下事情:
重新设计某些内容以使其具有反应性的关键是确保代码中的所有内容都成为某种触发器。如果您需要流中的某些逻辑,则回调不会做太多。
以下是一个例子:
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
但我想这是值得的另一个问题。