地理编码器对于搜索视图来说太慢了

Geocoder is too slow for searchview

我有以下代码:

Handler mHandler = new Handler(); //global variable

searchAddress.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {

            mHandler.removeCallbacksAndMessages(null);
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    try {
                        List<Address> foundAddresses = gc.getFromLocationName(newText,10);
                        Log.e("res",foundAddresses.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }, 0);
            
        return true;
    }
});

问题是,当我尝试更改位置名称时,总是有办法在搜索视图字段上出现较大延迟。它不运行顺利就好了。例如在 google 地图中。 我尝试使用 AynchTask 但结果比使用 Handler.

差得多

有没有办法针对性能问题进一步优化我的代码? 现在它看起来太丑了,因为当输入一个字符时,在字符出现在搜索视图字段之前总是有 2 秒的延迟。

我发现一个大问题 - 您的代码并没有真正取消任何 API 调用。假设用户键入“the”。假设他每秒键入 5 个键。所以在时间 t=0,他键入 t。在 t=5ms 左右,您的 onQueryTextChange 将被调用。在时间 t=6 毫秒左右,您的 onPostDelayed 将 运行 并进行 API 调用。

现在 h 在 t=200 毫秒内出现。在 2=205 毫秒,您取消所有消息。问题是消息已经 运行。所以你什么都不取消。这意味着如果他以每秒 5 个键的速率键入,那么您每秒进行 5 api 次调用。

post 中的延迟应该足够大,以便它检测实际的打字延迟,而不是按字符触发。否则你只会收到大量 API 的呼叫。更糟糕的是,如果出于某种原因 API 在 API 调用 1 之前调用 2 returns,你就会面临竞争条件。为了获得更好的延迟效果,我会使用打字训练器,看看会发生什么你的 wpm 是,并用它来计算一个合理的延迟,可能是你的角色平均时间的 2 倍。这是一个很好的第一关。

此外,Google 地图在本地缓存了大量数据。他们不太可能 运行 所有字符都匹配回服务器。至少他们会使用缓存的本地数据来快速获得结果,并使用网络来获得更详细的结果。