How to improve performance of google places autocomplete suggestions?

早过忘川 提交于 2019-12-06 05:23:21

问题


I am using google places autocomplete suggestions in my application. It is working fine but i want to improve its performance. When user types a place, it is giving a suggestions after a long delay or sometimes after deleting the last characters. How do i improve it's performance? Please help me. Thanks in advance

Here is my code

public class invoice extends Activity
{

AutoCompleteTextView edit_destination;
DownloadTask placesDownloadTask;
DownloadTask placeDetailsDownloadTask;
ParserTask placesParserTask;
ParserTask placeDetailsParserTask;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub    
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.create_invoice_activity);

edit_destination=(AutoCompleteTextView) findViewById(R.id.destination);
    edit_destination.setThreshold(1);       

    edit_destination.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {   
            // Creating a DownloadTask to download Google Places matching "s"
            placesDownloadTask = new DownloadTask(PLACES);

            // Getting url to the Google Places Autocomplete api
            String url = getAutoCompleteUrl(s.toString());

            // Start downloading Google Places
            // This causes to execute doInBackground() of DownloadTask class
            placesDownloadTask.execute(url);
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub              
        }
    }); 

    edit_destination.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int index,
                        long id) {

                ListView lv = (ListView) arg0;
                SimpleAdapter adapter = (SimpleAdapter) arg0.getAdapter();

                HashMap<String, String> hm = (HashMap<String, String>) adapter.getItem(index);


                selected_place=hm.get("description");


                // Creating a DownloadTask to download Places details of the selected place
                placeDetailsDownloadTask = new DownloadTask(PLACES_DETAILS);

                // Getting url to the Google Places details api
                String url = getPlaceDetailsUrl(hm.get("reference"));                   

                // Start downloading Google Place Details
                // This causes to execute doInBackground() of DownloadTask class
                placeDetailsDownloadTask.execute(url);

        }
    });     

}


private String getAutoCompleteUrl(String place){

        // Obtain browser key from https://code.google.com/apis/console
        String key = "YOUR KEY";

        // place to be be searched
        String input = "input="+place;

        // place type to be searched
        String types = "types=geocode";

        // Sensor enabled
        String sensor = "sensor=false";         

        // Building the parameters to the web service
        String parameters = input+"&"+types+"&"+sensor+"&"+key;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/place/autocomplete/"+output+"?"+parameters;

        return url;
    }


    private String getPlaceDetailsUrl(String ref){

        // Obtain browser key from https://code.google.com/apis/console
        String key = "YOUR KEY";

        // reference of place
        String reference = "reference="+ref;                    

        // Sensor enabled
        String sensor = "sensor=false";         

        // Building the parameters to the web service
        String parameters = reference+"&"+sensor+"&"+key;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/place/details/"+output+"?"+parameters;

        return url;
    }

    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
                URL url = new URL(strUrl);

                // Creating an http connection to communicate with url 
                urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url 
                urlConnection.connect();

                // Reading data from url 
                iStream = urlConnection.getInputStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

                StringBuffer sb  = new StringBuffer();

                String line = "";
                while( ( line = br.readLine())  != null){
                        sb.append(line);
                }

                data = sb.toString();

                br.close();

        }catch(Exception e){
                Log.d("Exception while downloading url", e.toString());
        }finally{
                iStream.close();
                urlConnection.disconnect();
        }
        return data;
     }


    // Fetches data from url passed
    private class DownloadTask extends AsyncTask<String, Void, String>{

        private int downloadType=0;

        // Constructor
        public DownloadTask(int type){
        this.downloadType = type;

        }

        @Override
        protected String doInBackground(String... url) {

            // For storing data from web service
            String data = "";

            try{
                // Fetching the data from web service
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;        
        }

        @Override
        protected void onPostExecute(String result) {           
            super.onPostExecute(result);        

            switch(downloadType){
            case PLACES:
                // Creating ParserTask for parsing Google Places
                placesParserTask = new ParserTask(PLACES);

                // Start parsing google places json data
                // This causes to execute doInBackground() of ParserTask class
                System.out.println(result);
                placesParserTask.execute(result);

                break;

            case PLACES_DETAILS : 
                // Creating ParserTask for parsing Google Places
                placeDetailsParserTask = new ParserTask(PLACES_DETAILS);

                // Starting Parsing the JSON string
                // This causes to execute doInBackground() of ParserTask class
                placeDetailsParserTask.execute(result);                             
            }           
        }       
    }     


    /** A class to parse the Google Places in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String,String>>>{

        int parserType = 0;

        public ParserTask(int type){
            this.parserType = type;
        }

        @Override
        protected List<HashMap<String, String>> doInBackground(String... jsonData) {

            JSONObject jObject;         
            List<HashMap<String, String>> list = null;           

            try{
                jObject = new JSONObject(jsonData[0]);

                switch(parserType){
                case PLACES :
                    PlaceJSONParser placeJsonParser = new PlaceJSONParser();
                    // Getting the parsed data as a List construct
                    list = placeJsonParser.parse(jObject);
                    break;
                case PLACES_DETAILS :                       
                    PlaceDetailsJSONParser placeDetailsJsonParser = new PlaceDetailsJSONParser();
                    // Getting the parsed data as a List construct
                    list = placeDetailsJsonParser.parse(jObject);
                }

            }catch(Exception e){
                Log.d("Exception",e.toString());
            }
            return list;
        }

        @Override
        protected void onPostExecute(List<HashMap<String, String>> result) {

                switch(parserType){
                case PLACES :
                    String[] from = new String[] { "description"};
                    int[] to = new int[] { android.R.id.text1 };

                    // Creating a SimpleAdapter for the AutoCompleteTextView
                    SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1, from, to);             

                    // Setting the adapter
                    edit_destination.setAdapter(adapter);                       
                    break;
                case PLACES_DETAILS :                       
                    HashMap<String, String> hm = result.get(0);

                    // Getting latitude from the parsed data 
                     latitude = Double.parseDouble(hm.get("lat"));

                    System.out.println(latitude);

                    // Getting longitude from the parsed data
                     longitude = Double.parseDouble(hm.get("lng"));     
                    System.out.println(longitude);


                    Toast.makeText(invoice.this, latitude+","+longitude , Toast.LENGTH_LONG).show();



                    SharedPreferences pref=getSharedPreferences("LOC", 0);


                    String S_lat,S_long;
                   S_lat=pref.getString("LAT", "");
                   S_long= pref.getString("LONG",""); 

                    source_lat=Double.parseDouble(S_lat);
                    source_long=Double.parseDouble(S_long);








                    break;                      
                }           
        }           
    }        

回答1:


Replace your "addTextChangedListener" method of autocompleteTextView with following code...

edit_destination.setOnKeyListener(new OnKeyListener() {
    public boolean onKey(View arg0, int arg1, KeyEvent arg2) {
        return false;
    }

});
edit_destination.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {   
        // Creating a DownloadTask to download Google Places matching "s"

        if(placesDownloadTask!=null)
        {                        
              Log.i("--placesDownloadTask--","progress_status : "+placesDownloadTask.getStatus());
              placesDownloadTask.cancel(true);      
        }


    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub      
        String chterm; 
        chterm=edit_destination.getText().toString();
        Log.i("---final selected text---", ""+chterm);
        placesDownloadTask = new DownloadTask(PLACES);

        // Getting url to the Google Places Autocomplete api
        String url = getAutoCompleteUrl(s.toString());

        // Start downloading Google Places
        // This causes to execute doInBackground() of DownloadTask class
        placesDownloadTask.execute(url);
    }
});

Instead of giving call from onTextChanged, give call from afterTextChanged it reduces the number of calls after each character and hence reduces the delays.

Try it out, It may help you lot.




回答2:


There is another method, as above one didn't work for me.
Replace your 'addTextChangedListener' with this one.

This will create a new timer every time it executes the onTextChanged() method and cancels the earlier assigned timertask.

edit_destination.addTextChangedListener(new TextWatcher() {

    Timer timer = new Timer();
    int DELAY = 3000;
    String chterm;
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Cancel the timer if already running. 
            timer.cancel();
            chterm = s.toString();

            // (Optional) Check if length of query is greater than 3
            if(s.length() >= 3) {
                // Start a new timer and assign a TimerTask to it.  
                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        Log.i("---final selected text---", "" + chterm);
                        // Getting url to the Google Places Autocomplete api
                        String url = getAutoCompleteUrl(chterm);
                        // Creating a DownloadTask to download Google Places matching "s"
                        placesDownloadTask = new DownloadTask(PLACES);
                        // Start downloading Google Places
                        // This causes to execute doInBackground() of DownloadTask class
                        placesDownloadTask.execute(url);
                    }
                }, DELAY);
            }
        }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub
    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub              
    }
}); 


来源:https://stackoverflow.com/questions/22060152/how-to-improve-performance-of-google-places-autocomplete-suggestions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!