Geocoder is too slow for searchview

Issue

I’ve got the following code:

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;
    }
});

The issue is that there is always a way to large delay on the searchviewfield when I’m trying to change the locationname. It does not run smoothly like for. e.g. in google maps. I tried using AynchTask but the result was much worse than using a Handler.

Is there a way to optimize my code much more for performance issue? Right now it looks just too ugly cause when a character is entered there is always a 2 second delay before the character appears on the searchviewfield.

Solution

I can see one big problem- your code isn’t really canceling any API calls. Let’s say the user type “the”. Let’s say he types 5 keys per second. So at time t0, he types t. at t5ms or so, your onQueryTextChange will be called. At time t6ms or so, your onPostDelayed will run and make an API call.

Now the h comes in a t200ms. At 2205 ms, you cancel all messages. The problem is the message has already run. So you cancel nothing. Which means if he’s typing a the rate of 5 keys per second, you’re making 5 api calls per second.

The delay in your post delay should be large enough that its detecting actual delays in typing, and not firing per character. Otherwise you just have a ton of API calls out. Worse, you open yourself to race conditions if for some reason API call 2 returns before API call 1. For a good number on delay, I’d use a typing trainer and see what your wpm is, and use that to figure out a reasonable delay of maybe 2x what your average time for a character is. That’s a good first pass at it.

Also, Google maps caches a significant amount of data locally. It’s unlikely they run all character by character matching back to the server. At the very least they’d use cached local data for fast results and network for more detailed results.

Answered By – Gabe Sechan

Leave a Comment