2014-02-27 112 views
4

我在我的應用程序中使用谷歌地方自動填充建議。它工作正常,但我想提高其性能。用戶輸入地點時,會在長時間延遲後或在刪除最後一個字符後提供建議。我如何改善它的表現? 請幫幫我。 在此先感謝如何提高谷歌自動填充建議的性能?

這裏是我的代碼

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

,你可以把它放在條件狀擠壓三個或四個單詞後應該火 –

+0

並從你的問題取下鑰匙其secreat –

+0

是的,我已經試過了。我已經設置了3而不是1的門檻,這意味着它會開始給3個字符後的建議,但不工作.. – Snehal

回答

4

與下面的代碼替換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); 
    } 
}); 

而不是給從onTextChanged電話,給來自afterTextChanged的呼叫減少了每個字符後的呼叫次數,從而減少了延遲。

試一試,它可能會幫助你很多。

+1

謝謝...它現在的作品令人驚歎...我得到的建議只要我開始打字..我已經放棄了所有的希望,但這段代碼幫了我很多......再次感謝很多.. :) – Snehal

1

還有另一種方法,如上所述,沒有爲我工作。
用這個替換你的'addTextChangedListener'。

這將在每次執行onTextChanged()方法時創建一個新的計時器,並取消先前分配的時間任務。

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