[英]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.