Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/235.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在Place API适配器中的Filter.performFiltering()中使用Rx debounce运算符_Android_Rx Java_Google Places Api_Debounce - Fatal编程技术网

Android 在Place API适配器中的Filter.performFiltering()中使用Rx debounce运算符

Android 在Place API适配器中的Filter.performFiltering()中使用Rx debounce运算符,android,rx-java,google-places-api,debounce,Android,Rx Java,Google Places Api,Debounce,我们的应用程序使用AutoCompleteTextView和Google places API搜索地点 我想添加debounce RxJava操作符来放置搜索。我不太擅长RxJava 适配器已实现getFilter(),并且筛选器具有performFiltering()覆盖,该覆盖将约束/查询作为字符串接收。 过滤器当前看起来如下所示: private inner class AutocompleteFilter : Filter() { @WorkerThread overr

我们的应用程序使用AutoCompleteTextView和Google places API搜索地点

我想添加debounce RxJava操作符来放置搜索。我不太擅长RxJava

适配器已实现getFilter(),并且筛选器具有performFiltering()覆盖,该覆盖将约束/查询作为字符串接收。
过滤器当前看起来如下所示:

private inner class AutocompleteFilter : Filter() {

    @WorkerThread
    override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
        val results = Filter.FilterResults()
        val search = constraint?.toString() ?: ""

        var found = emptyList<PlaceData>()

        // quick reply on empty search
        val bounds = latLngBounds
        if (!TextUtils.isEmpty(search) && bounds != null) {
            found = placesApiHelper.fetchAutocompletePredictions(search, bounds)
                    .timeout(1000L, TimeUnit.MILLISECONDS)
                    .toList()
                    .doOnError {
                        searchResultSubject.onNext(false)
                        logTo(log).warning("Timeout or error happens. %s", it)
                    }
                    .doOnSuccess {
                        searchResultSubject.onNext(true)
                    }
                    .onErrorReturn { emptyList() }
                    .blockingGet()
        }

        results.values = found
        results.count = found.size

        return results
    }

    @MainThread
    override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults) {
        logTo(log).info("publishing results. Found: %s items", results.count)

        data.clear()

        val list = results.values as? List<*>
        list?.let {
            val values = it.filterIsInstance<PlaceData>()
            if (values.isNotEmpty()) {
                data.addAll(values)
                notifyDataSetChanged()
            }
        }
    }
}
 private fun fetchAutocompletePredictions(query: String, latLngBounds: LatLngBounds): Observable<PlaceData> {
    Timber.d("places api request: %s (total: %s, cached: %s)", query, PlacesApiCache.CALLS.incrementAndGet(), PlacesApiCache.HITS.get())

    val rectangularBounds = toRectangularBounds(latLngBounds)

    val request = FindAutocompletePredictionsRequest.builder()
            .setLocationBias(rectangularBounds)
            .setQuery(query)
            .build()

    return Observable.create {
        placesClient.findAutocompletePredictions(request).addOnSuccessListener { response ->

            val predictions = response.autocompletePredictions
            val results = mutableListOf<PlaceData>()

            for (i in 0 until Math.min(predictions.size, MAX_RESULTS)) {
                results.add(placeDataFrom(predictions[i]))
            }

            PlacesApiCache.cacheData(query, results)

            for (result in results) {
                it.onNext(result)
            }

            it.onComplete()
        }.addOnFailureListener { exception ->
            if (exception is ApiException) {
                Timber.e("Place not found: %s", exception.getStatusCode())
            }
            it.onError(exception)
        }
    }
}
私有内部类自动完成过滤器:过滤器(){
@工作线程
重写性能筛选(约束:CharSequence?):Filter.FilterResults{
val results=Filter.FilterResults()
val搜索=约束?.toString()?:“”
var found=emptyList()
//空搜索的快速回复
val bounds=latLngBounds
如果(!TextUtils.isEmpty(搜索)&&bounds!=null){
found=placesApiHelper.fetchAutocompletePredictions(搜索,边界)
.超时(1000L,时间单位为毫秒)
托利斯先生()
杜恩先生{
SearchResultsObject.onNext(false)
logTo(log)。警告(“发生超时或错误。%s”,it)
}
杜恩塞斯先生{
SearchResultsObject.onNext(true)
}
.onErrorReturn{emptyList()}
.blockingGet()
}
results.values=找到
results.count=found.size
返回结果
}
@主线
重写fun publishResults(约束:CharSequence?,结果:Filter.FilterResults){
logTo(log.info)(“发布结果。找到:%s个项目”,结果。计数)
data.clear()
val list=结果。值为?列表
名单?让我看看{
val values=it.filterIsInstance()
if(values.isNotEmpty()){
data.addAll(值)
notifyDataSetChanged()
}
}
}
}
fetchAutoCompletePredictions()如下所示:

private inner class AutocompleteFilter : Filter() {

    @WorkerThread
    override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
        val results = Filter.FilterResults()
        val search = constraint?.toString() ?: ""

        var found = emptyList<PlaceData>()

        // quick reply on empty search
        val bounds = latLngBounds
        if (!TextUtils.isEmpty(search) && bounds != null) {
            found = placesApiHelper.fetchAutocompletePredictions(search, bounds)
                    .timeout(1000L, TimeUnit.MILLISECONDS)
                    .toList()
                    .doOnError {
                        searchResultSubject.onNext(false)
                        logTo(log).warning("Timeout or error happens. %s", it)
                    }
                    .doOnSuccess {
                        searchResultSubject.onNext(true)
                    }
                    .onErrorReturn { emptyList() }
                    .blockingGet()
        }

        results.values = found
        results.count = found.size

        return results
    }

    @MainThread
    override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults) {
        logTo(log).info("publishing results. Found: %s items", results.count)

        data.clear()

        val list = results.values as? List<*>
        list?.let {
            val values = it.filterIsInstance<PlaceData>()
            if (values.isNotEmpty()) {
                data.addAll(values)
                notifyDataSetChanged()
            }
        }
    }
}
 private fun fetchAutocompletePredictions(query: String, latLngBounds: LatLngBounds): Observable<PlaceData> {
    Timber.d("places api request: %s (total: %s, cached: %s)", query, PlacesApiCache.CALLS.incrementAndGet(), PlacesApiCache.HITS.get())

    val rectangularBounds = toRectangularBounds(latLngBounds)

    val request = FindAutocompletePredictionsRequest.builder()
            .setLocationBias(rectangularBounds)
            .setQuery(query)
            .build()

    return Observable.create {
        placesClient.findAutocompletePredictions(request).addOnSuccessListener { response ->

            val predictions = response.autocompletePredictions
            val results = mutableListOf<PlaceData>()

            for (i in 0 until Math.min(predictions.size, MAX_RESULTS)) {
                results.add(placeDataFrom(predictions[i]))
            }

            PlacesApiCache.cacheData(query, results)

            for (result in results) {
                it.onNext(result)
            }

            it.onComplete()
        }.addOnFailureListener { exception ->
            if (exception is ApiException) {
                Timber.e("Place not found: %s", exception.getStatusCode())
            }
            it.onError(exception)
        }
    }
}
AutoCompletePredictions(查询:字符串,latLngBounds:latLngBounds):可观察{
Timber.d(“places api请求:%s(总数:%s,缓存:%s)”,查询,PlacesApiCache.CALLS.incrementAndGet(),PlacesApiCache.HITS.get()
val rectangularBounds=toRectangularBounds(latLngBounds)
val request=FindAutocompletePredictionsRequest.builder()
.setLocationBias(矩形边界)
.setQuery(查询)
.build()
返回可观察的。创建{
placesClient.FindAtoCompletePredictions(请求).addOnSuccessListener{response->
val预测=响应。自动完成预测
val results=mutableListOf()
对于(i在0中直到Math.min(predicts.size,MAX_结果)){
结果.添加(placeDataFrom(预测[i]))
}
PlacesApiCache.cacheData(查询、结果)
for(结果中的结果){
it.onNext(结果)
}
it.onComplete()
}.addOnFailureListener{异常->
如果(异常为ApiException){
Timber.e(“未找到位置:%s”,exception.getStatusCode())
}
it.onError(例外)
}
}
}
我试图使用PublichSubject(来自JakeWharton库的PublishRelay),但我仍然没有信心通过此调用(获取约束)修复它,因为事件在这里发生,同样的方法也应该返回FIlterResult。这意味着观察者也应该被置于performFiltering()中。这意味着对于每个字母条目,此方法都会命中多个观察者。
而且,我应该使用与新的搜索任务(约束)相同的方法来调用subject.onNext()

在这种情况下,如何使用debounce运算符使整个过程同步,并在结束时返回FIlterResults


提前谢谢

我去掉了过滤器。我没有让过滤器回调得到关于新搜索字符串的通知,而是添加了我自己的publishSubject来观察新搜索字符串并通知观察者

Own observer(使用publicSubject而不是filter回调)允许我在流中插入debounce操作符

在适配器中添加了以下内容:

private var queryPlacesSubject = PublishSubject.create<String>()

init {
    subscribeForPlacePredictions()
}

private fun subscribeForPlacePredictions() {
    queryPlacesSubject
            .debounce(DEBOUNCE_TIME_MILLIS, TimeUnit.MILLISECONDS)
            .distinctUntilChanged()
            .observeOn(Schedulers.newThread())
            .doOnNext { findPlacePredictions(it) }
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext {notifyThePlacesChanged()}
            .subscribeOn(Schedulers.io())
            .subscribe()
}

fun setQuery(query: String) {
    queryPlacesSubject.onNext(query)
}
    private fun findPlacePredictions(query: String?) {
    val search = query ?: ""

    // save entered text by user for highlight operations
    highlight = search

    // we should be in background thread already
    var found = emptyList<PlaceData>()

    // quick reply on empty search
    val bounds = latLngBounds
    if (!TextUtils.isEmpty(search) && bounds != null) {
        found = placesApiHelper.requestAutocomplete(search, bounds)
                .timeout(runtime.timeoutAutocompleteSearch(), TimeUnit.MILLISECONDS)
                .toList()
                .doOnError {
                    searchResultSubject.onNext(false)
                    logTo(log).warning("Timeout or error happens. %s", it)
                }
                .doOnSuccess {
                    searchResultSubject.onNext(true)
                }
                .onErrorReturn { emptyList() }
                .blockingGet()
    }

    data.clear()
    data.addAll(found)
}

private fun notifyThePlacesChanged() {
    notifyDataSetChanged()
}

我去掉了过滤器。我没有让过滤器回调得到关于新搜索字符串的通知,而是添加了我自己的publishSubject来观察新搜索字符串并通知观察者

Own observer(使用publicSubject而不是filter回调)允许我在流中插入debounce操作符

在适配器中添加了以下内容:

private var queryPlacesSubject = PublishSubject.create<String>()

init {
    subscribeForPlacePredictions()
}

private fun subscribeForPlacePredictions() {
    queryPlacesSubject
            .debounce(DEBOUNCE_TIME_MILLIS, TimeUnit.MILLISECONDS)
            .distinctUntilChanged()
            .observeOn(Schedulers.newThread())
            .doOnNext { findPlacePredictions(it) }
            .observeOn(AndroidSchedulers.mainThread())
            .doOnNext {notifyThePlacesChanged()}
            .subscribeOn(Schedulers.io())
            .subscribe()
}

fun setQuery(query: String) {
    queryPlacesSubject.onNext(query)
}
    private fun findPlacePredictions(query: String?) {
    val search = query ?: ""

    // save entered text by user for highlight operations
    highlight = search

    // we should be in background thread already
    var found = emptyList<PlaceData>()

    // quick reply on empty search
    val bounds = latLngBounds
    if (!TextUtils.isEmpty(search) && bounds != null) {
        found = placesApiHelper.requestAutocomplete(search, bounds)
                .timeout(runtime.timeoutAutocompleteSearch(), TimeUnit.MILLISECONDS)
                .toList()
                .doOnError {
                    searchResultSubject.onNext(false)
                    logTo(log).warning("Timeout or error happens. %s", it)
                }
                .doOnSuccess {
                    searchResultSubject.onNext(true)
                }
                .onErrorReturn { emptyList() }
                .blockingGet()
    }

    data.clear()
    data.addAll(found)
}

private fun notifyThePlacesChanged() {
    notifyDataSetChanged()
}

我希望Places API builder能够帮助消除公告,并为应用程序做这些事情。但事实并非如此。当然,他们为什么要鼓励。让应用程序调用API并增加成本。:)我希望Places API builder能够帮助消除公告,并为应用程序做这些事情。但事实并非如此。当然,他们为什么要鼓励。让应用程序调用API并增加成本。:)