我正在尝试获取AutoCompleteTextView(ACTV)来显示结果,我是从网络资源中获得的。我已经将完成率设置为2,并且可以看到当我输入字符时会发出请求。

我得到的结果是正确的。可以说我写“ CA”,然后将结果“汽车”作为自动完成。我有一个回调函数,该函数从异步箱中接收结果,并将结果放入阵列ADADAPTER中。然后,我在ACTV上调用.showdropdown(),并显示一个空的下拉次数(比普通元素的大小的一半)。然后,如果我输入最后一个字母“ r”并显示“汽车”,则显示下拉列表,结果突然在列表中。

如果我输入两个字符(返回有效结果),然后删除最后一个字母,也会发生同样的情况。删除字母时,“汽车”将显示为自动完成值。

有人有这个问题吗?看起来适配器充满了结果,但是直到我采取的下一个操作之前,结果才显示。在将结果添加到适配器中后,我还尝试运行.notifyDataSetchanged(),但不需要?

有帮助吗?

解决方案

没有看到您的代码,很难说会发生什么。但是,想到的第一件事是您的网络请求正在其他线程上发生,因此 performFiltering() 可能会过早返回空结果集。在那时候, publishResults() 正在返回空的结果,您的下拉为空。稍后,您的异步将结果恢复,然后将结果添加到适配器的列表中,但是由于某种原因,它尚未显示。

我认为您可能会误认为需要异步。过滤器对象已经在做类似于Asynctask的事情: performFiltering() 是在背景线程中完成的, publishResults() 从UI线程调用,pershialFiltering()完成后。因此,您可以直接在perstrifteltering()中直接执行网络请求,并将结果设置为filterResults对象,并且您不必担心网络请求太慢并在UI中引起问题。

一种替代解决方案,稍微复杂一些,但这是我在过滤对象中所做的(由于现有的架构在后台进行API调用,使用异步回调,而不是dermanderfertering所需的阻止/同步步骤( ),是使用wait()/notify()进行跨线程监视的同步对象,因此效果与直接在perform-filtering()中直接执行网络请求()相同,但实际上是在多个线程中发生的:

// in Filter class..
protected FilterResults performFiltering(CharSequence constraint) {

    APIResult response = synchronizer.waitForAPI(constraint);
    // ...
}

// callback invoked after the API call finishes:
public void onAPIComplete(APIResult results) {
    synchronizer.notifyAPIDone(results);
}

private class Synchronizer {
    APIResult result;

    synchronized APIResult waitForAPI(CharSequence constraint) {
        someAPIObject.startAsyncNetworkRequest(constraint);
        // At this point, control returns here, and the network request is in-progress in a different thread.
        try {
            // wait() is a Java IPC technique that will block execution until another
            // thread calls the same object's notify() method.
            wait();
            // When we get here, we know that someone else has just called notify()
            // on this object, and therefore this.result should be set.
        } catch(InterruptedException e) { }
        return this.result;
    }

    synchronized void notifyAPIDone(APIResult result) {
        this.result = result;
        // API result is received on a different thread, via the API callback.
        // notify() will wake up the other calling thread, allowing it to continue
        // execution in the performFiltering() method, as usual.
        notify();
    }
}

但是,我认为您可能会发现最简单的解决方案是直接在Perform -Filtering()方法中同步执行网络请求。上面的代码示例只是一种可能性,如果您已经对异步/回调驱动的API调用的体系结构进行了适当的状态,并且您不想更改该行为以在Perform-Filtering()中获得同步结果()。

其他提示

我认为乔的答案是必经之路。但是,我认为您应该使用 Countdownlatch 而不是等待/通知。

原因是,如果您的API真正快速返回“ Wait()” ...在这种情况下,Notify不会有效果,并且Wait()将无限期地等待。使用闩锁,该代码将看起来像这样(从Joe复制并修改):

// in Filter class..
protected FilterResults performFiltering(CharSequence constraint) {
  APIResult response = synchronizer.waitForAPI(constraint);
  // ...
}

// callback invoked after the API call finishes:
public void onAPIComplete(APIResult results) {
  synchronizer.notifyAPIDone(results);
}

private class Synchronizer {
  APIResult result;
  CountDownLatch latch;

  synchronized APIResult waitForAPI(CharSequence constraint) {
      latch = new CountDownLatch(1);
      someAPIObject.startAsyncNetworkRequest(constraint);
      // At this point, control returns here, and the network request is in-progress in a different thread.
      try {
        // Will wait till the count is 0...
        // If the count is already 0, it'll return immediately. 
        latch.await();
        // When we get here, we know that someone else has just called notify()
        // on this object, and therefore this.result should be set.
    } catch(InterruptedException e) { }
    return this.result;
  }

  synchronized void notifyAPIDone(APIResult result) {
    this.result = result;
    // API result is received on a different thread, via the API callback.
    // countDown() will wake up the other calling thread, allowing it to continue
    // execution in the performFiltering() method, as usual.
    latch.countDown();
  }
}

最后,我没有足够的信用来发表评论,否则我会...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top