2016-03-06 5 views
1

Я хотел бы использовать RxJava задушить количество AccessibilityEvent-х я получаю от android.accessibilityservice.AccessibilityService в частности TYPE_VIEW_TEXT_CHANGED event.Дроссель вызова метода RxJava

Он запускается каждый раз, когда пользователь набирает что-либо в виде виджета 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

Так что мой вывод может быть:

[это]

[это является]

[это тест]

вместо:

[т]

[й]

[Тхи]

[это]

...

Заранее спасибо!

+0

Что означает: «Однако я не уверен, как именно я должен использовать их, если у меня еще нет всех событий, которые я хочу испустить». ? У вас возникли проблемы с созданием наблюдаемого события? Или просто выбрать правильный оператор фильтра? –

+0

Я в основном хочу добавить объекты в мой onNext после того, как создал свой Observable. И затем примените правильный фильтр, чтобы получить желаемый результат. Если бы у меня был список с событиями, когда я сделал наблюдаемый, я мог бы просто использовать Observable.from(), но я хочу «нажимать» события на мои наблюдаемые. – tim

+0

Так в чем проблема с использованием debounce? Можете ли вы опубликовать свой rx-код? –

ответ

0

OK.

Я узнал, что есть что-то вроде PublishSubject/Subject.

В основном я могу отправить в onNext как своего рода сеттер после создания Observable, что и было тем, что я был после.

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 

Но я думаю, что здесь стоит другой вопрос.

1

Я хотел бы сделать следующее:

  • Создать наблюдаемым, который устанавливает «доступность слушателя»
  • Этот слушатель может начать поток 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, так как важно отказаться от подписки, чтобы предотвратить утечку памяти!

Смежные вопросы