我得到了以下代码:
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;
}
});
问题是,当我试图更改位置名称时,总有一种方法会导致searchview字段出现大延迟。它不像for那样平稳运行。例如在谷歌地图中。我尝试使用AynchTask
,但结果比使用Handler
差得多。
有没有一种方法可以针对性能问题对我的代码进行更多的优化?现在它看起来太难看了,因为当输入一个字符时,在该字符出现在searchview字段上之前总是有2秒的延迟。
我看到了一个大问题——您的代码并没有真正取消任何API调用。假设用户键入";";。假设他每秒键入5个键。因此,在t=0时,他键入t。在t=5ms左右,将调用onQueryTextChange。在时间t=6ms左右时,onPostDelayed将运行并进行API调用。
现在h在t=200ms时出现。在2=205毫秒时,取消所有消息。问题是消息已经运行。所以你什么都不取消。这意味着,如果他以每秒5个键的速率键入,那么你每秒将进行5次api调用。
发布延迟中的延迟应该足够大,以检测键入中的实际延迟,而不是每个字符触发。否则,您只需要调用大量的API。更糟糕的是,如果出于某种原因API调用2在API调用1之前返回,您将面临竞争条件。对于一个好的延迟数字,我会使用打字训练器,看看你的wpm是多少,然后用它来计算出一个合理的延迟,可能是你对一个角色的平均时间的2倍。这是一个很好的第一步。
此外,谷歌地图在本地缓存了大量数据。他们不太可能将所有逐个字符的匹配都运行回服务器。至少,他们会使用缓存的本地数据来获得快速结果,并使用网络来获得更详细的结果。