我有一个地图活动,它的顶部还有一个EditText,并且我想在地图上有拖曳时在该EditText中显示更改的地址。我目前正在使用Geocoder类,以根据地图提供的坐标检索地址。但是这种方式在流畅的地图拖动动作中造成了很大的滞后。有没有更好的方法来检索地址,或者有更有效的方法来使用Geocoder类?现在,我已经在地图的OnCameraChangeListener事件中实现了getAddress()方法。这是代码。
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
double latitude=mMap.getCameraPosition().target.latitude;
double longitude=mMap.getCameraPosition().target.longitude;
String _Location="";
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if(null!=listAddresses&&listAddresses.size()>0){
_Location = listAddresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
}
EditText addressTxt=(EditText) findViewById(R.id.search_address_txt);
addressTxt.setText(_Location);
}
});
我看到另一个应用程序实现了,其中搜索的地址位于地图拖动的末尾,并且地图的运动没有滞后。
该Geocoder$getFromLocation()
是阻塞调用,直到手段的API返回的地址将冻结UI线程。唯一的解决方案是在后台线程上运行此调用。
有两种方法可以实现此目的:
Intent Service
。您可以在此处找到有关如何操作的详细信息。就我个人而言,我认为这过于矫kill而且非常复杂。AsyncTask
。请参阅此内容以获取总体思路并根据您的需求实施。此外,如果您使用的是Rx,则可以从地址解析器启动一个新的可观察对象,并在其他线程上进行观察,然后在主线程上进行订阅。
更新:我从一个旧项目中提取了此代码,看看是否有帮助。
AsyncGeocoderObject.java // object to pass to asynctask
public class AsyncGeocoderObject {
public Location location; // location to get address from
Geocoder geocoder; // the geocoder
TextView textView; // textview to update text
public AsyncGeocoderObject(Geocoder geocoder, Location location, TextView textView) {
this.geocoder = geocoder;
this.location = location;
this.textView = textView;
}
}
AsyncTask的实现
public class AsyncGeocoder extends AsyncTask<AsyncGeocoderObject, Void, List<Address>> {
private TextView textView;
@Override
protected List<Address> doInBackground(AsyncGeocoderObject... asyncGeocoderObjects) {
List<Address> addresses = null;
AsyncGeocoderObject asyncGeocoderObject = asyncGeocoderObjects[0];
textView = asyncGeocoderObject.textView;
try {
addresses = asyncGeocoderObject.geocoder.getFromLocation(asyncGeocoderObject.location.getLatitude(),
asyncGeocoderObject.location.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
return addresses;
}
@Override
protected void onPostExecute(List<Address> addresses) {
Log.v("onPostExecute", "location: " + addresses);
String address;
if (addresses != null)
address = addresses.get(0).getLocality() + ", " + addresses.get(0).getCountryName();
else address = "Service unavailable.";
textView.setText(address);
}
}
位置更改时调用方法:
new AsyncGeocoder().execute(new AsyncGeocoderObject(
new Geocoder(this),
location,
locationTV
));
希望这可以帮助!
更新2:
有关如何实现上述说明:
AsyncGeocoderObject
并复制内容AsyncGeocoder
然后复制内容。现在,说您想获得用户的位置MainActivity
并在textview中显示地址,例如locationTV
。实例化textview后,创建的新对象AsyncGeocoder
并传递参数。例如:
// in onCreate()
new AsyncGeocoder().execute(new AsyncGeocoderObject(
new Geocoder(this), // the geocoder object to get address
location, // location object,
locationTV // the textview to set address on
));
另外,如果您没有位置对象,请使用所拥有的经度和纬度进行创建。有关如何操作,请参见这篇文章。
希望这对您有所帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句