2016-03-06 40 views
1

我想用RxJava來節流AccessibilityEvent的數量,我從android.accessibilityservice.AccessibilityService特別是TYPE_VIEW_TEXT_CHANGED event得到。油門方法調用RxJava

每當用戶鍵入EditText小部件中的任何內容時,它都會被觸發。不過,我嘗試使用debounce,throttleLastthrottleFirst或甚至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]

[日]

[THI]

[這]

...

提前感謝!

+0

什麼意思:'但是我不確定我應該如何使用它們,如果我還沒有發完所有事件的話。 ? 您是否在創建一個從您的事件obetable問題? 或者只是選擇正確的過濾器運算符? –

+0

我基本上想在創建我的Observable後將對象添加到我的onNext。然後應用正確的過濾器來獲得我想要的輸出。如果我在創建可觀察事件時將事件列表與事件相關聯,那麼我可以使用Observable.from(),但是我想將事件「推送」給可觀察事件。 – tim

+0

那麼使用去抖動有什麼問題?你能不能發佈你的rx相關代碼? –

回答

0

好的。

我發現有東西作爲PublishSubject/Subject

我創建Observable之後,我基本上可以將它作爲某種設置器發佈到onNext。

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; 
     } 
    } 
} 

這是這個問題的答案。但是我面臨的是空物體,因爲它們是。

@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的引用,因爲爲了防止內存泄漏,取消訂閱非常重要!