简体   繁体   English

如何提高谷歌地方自动填充建议的性能?

[英]How to improve performance of google places autocomplete suggestions?

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

Replace your "addTextChangedListener" method of autocompleteTextView with following code... 用以下代码替换autocompleteTextView的“addTextChangedListener”方法...

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. 不是从onTextChanged发出调用,而是从afterTextChanged调用它,它减少了每个字符后的调用次数,从而减少了延迟。

Try it out, It may help you lot. 尝试一下,它可能对你有所帮助。

There is another method, as above one didn't work for me. 还有另一种方法,如上所述,对我来说不起作用。
Replace your 'addTextChangedListener' with this one. 用这个替换'addTextChangedListener'。

This will create a new timer every time it executes the onTextChanged() method and cancels the earlier assigned timertask. 这将在每次执行onTextChanged()方法时创建一个新的计时器,并取消先前分配的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              
    }
}); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM