#android #performance #handler #geocoding #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 { Listlt;Addressgt; foundAddresses = gc.getFromLocationName(newText,10); Log.e("res",foundAddresses.toString()); } catch (IOException e) { e.printStackTrace(); } } }, 0); return true; } });
Проблема в том, что всегда есть возможность большой задержки в поле searchviewполе, когда я пытаюсь изменить имя местоположения. Это не работает гладко, как, например, в google maps. Я попробовал использовать AynchTask
, но результат был намного хуже, чем при использовании Handler
.
Есть ли способ значительно оптимизировать мой код для решения проблем с производительностью? Прямо сейчас это выглядит слишком уродливо, потому что при вводе символа всегда возникает задержка в 2 секунды, прежде чем символ появится в поле поиска.
Комментарии:
1.
Is there a way to optimize my code much more for performance issue?
ну, не уверен, что это как-то связано с производительностью, если это вызов api и завершение вызова api занимает 1-2 секунды, то вы мало что можете с этим поделать2. @a_local_nobody, я думаю, тогда google использует другой подход? потому что, насколько я знаю, они дают результаты намного быстрее с тем же api
3. да, я бы предположил, что реализации этого используют списки данных, которые уже кэшированы, не имело бы смысла искать все местоположения, начинающиеся с X, по вызову api, когда кто-то вводит, но было бы разумнее получить большой список местоположений, начинающихся с X, а затем автоматически заполнять их на основе того, что вводит пользователь. запрос предложений по библиотекам здесь не по теме, и людям не рекомендуется их выдавать, но api Places делает этот тип операций довольно простым, в зависимости от того, что вам нужно, возможно, это может вам помочь
Ответ №1:
Я вижу одну большую проблему — ваш код на самом деле не отменяет никаких вызовов API. Допустим, пользователь наберет «the». Допустим, он набирает 5 клавиш в секунду. Поэтому в момент времени t=0 он набирает t. при t=5 мс или около того будет вызван ваш onQueryTextChange. Во время t=6 мс или около того ваш onPostDelayed запустится и вызовет API.
Теперь h приходит через t=200 мс. Через 2=205 мс вы отменяете все сообщения. Проблема в том, что сообщение уже запущено. Так что вы ничего не отменяете. Это означает, что если он печатает со скоростью 5 клавиш в секунду, вы совершаете 5 вызовов api в секунду.
Задержка в вашей задержке публикации должна быть достаточно большой, чтобы она обнаруживала фактические задержки при вводе, а не запускала каждый символ. В противном случае у вас просто будет куча вызовов API. Хуже того, вы открываетесь для условий гонки, если по какой-то причине вызов API 2 возвращается до вызова API 1. Для хорошего числа задержек я бы использовал тренажер для набора текста и посмотрел, каков ваш wpm, и использовал его, чтобы определить разумную задержку, возможно, в 2 раза превышающую ваше среднее время для персонажа. Это хороший первый проход в этом деле.
Кроме того, Google maps кэширует значительный объем данных локально. Маловероятно, что они запускают все сопоставление символов по символам обратно на сервер. По крайней мере, они будут использовать кэшированные локальные данные для быстрых результатов и сеть для более подробных результатов.