节流方法调用 RxJava
Throttle method call RxJava
我想使用 RxJava
来限制我从 android.accessibilityservice.AccessibilityService
获得的 AccessibilityEvent
的数量,特别是 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! ");
}
}
我想要在这个 EditText
小部件上使用类似于 debounce
的东西
Kaushik Gopal's DebounceSearchEmitterFragment.java
所以我的输出可以是:
[这是]
[这是一个]
[这是一个测试]
而不是:
[t]
[次]
[你]
[这个]
...
提前致谢!
我会做以下事情:
- 创建一个设置 "accessibility listener"
的可观察对象
- 此侦听器可以启动 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
的引用,因为取消订阅以防止内存泄漏很重要!
好的。
我发现有一个 PublishSubject
/Subject
.
在创建 Observable
之后,我基本上可以 post 到 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;
}
}
}
这就是这个问题的答案。但是我面临着空对象,因为它们被 android.accessibilityservice.AccessibilityService
中的 executeMessage
回收。
@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
但我想这里值得再问一个问题。
我想使用 RxJava
来限制我从 android.accessibilityservice.AccessibilityService
获得的 AccessibilityEvent
的数量,特别是 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! ");
}
}
我想要在这个 EditText
小部件上使用类似于 debounce
的东西
Kaushik Gopal's DebounceSearchEmitterFragment.java
所以我的输出可以是:
[这是]
[这是一个]
[这是一个测试]
而不是:
[t]
[次]
[你]
[这个]
...
提前致谢!
我会做以下事情:
- 创建一个设置 "accessibility listener" 的可观察对象
- 此侦听器可以启动 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
的引用,因为取消订阅以防止内存泄漏很重要!
好的。
我发现有一个 PublishSubject
/Subject
.
在创建 Observable
之后,我基本上可以 post 到 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;
}
}
}
这就是这个问题的答案。但是我面临着空对象,因为它们被 android.accessibilityservice.AccessibilityService
中的 executeMessage
回收。
@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
但我想这里值得再问一个问题。