我担心在主线程上查找位置信息(使用反向地理编码)会降低我的UI速度。为了解决这个问题,我将信息放入AsyncTask(下面的代码)现在我想添加位置监听器,我遇到了各种各样的问题。
我做了一些研究,现在想知道......是否有必要将位置代码放在AsyncTask中?也许Android只是“自然地”异步找到位置信息?
public class LocationAsyncTask extends AsyncTask<Void, String, String> {
@Override protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tvLocation.setText(result);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
tvLocation.setText("Finding current location");
}
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(criteria, true);
Location location =locationManager.getLastKnownLocation(provider);
String strUpdateResult = updateWithANewLocation(location);
//locationManager.requestLocationUpdates(provider, 1000, 10, locationListener);
return strUpdateResult;
}
private String updateWithANewLocation(Location location) {
// TODO Auto-generated method stub
StringBuilder sbLocation = new StringBuilder();
String strLocation = new String();
TextView myLocationText;
String addressString = "No address found";
String latLongString = "";
//If there is a location
if (location!= null) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
double altitude = location.getAltitude();
float accuracy = location.getAccuracy();
float bearing = location.getBearing();
long time = location.getTime();
float speed = location.getSpeed();
String prov = location.getProvider();
strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n" ;
publishProgress(strLocation);
Geocoder gc = new Geocoder(LateRunner.this, Locale.getDefault());
try {
List<Address> addresses = gc.getFromLocation(latitude, longitude, 1);
//if location and then address is found
if (addresses.size() > 0 ) {
Address address = addresses.get(0);
for (int i=0; i <address.getMaxAddressLineIndex(); i++) {
sbLocation.append(address.getAddressLine(i)).append("\n");
}
strLocation= sbLocation.toString();
publishProgress(strLocation);
}
//if location but no address
else {
strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n";
publishProgress(strLocation);
} //end try
} catch (IOException e) {
strLocation = "Latitude: " + latitude + "\nLongitude: " + longitude + "\n";
publishProgress(strLocation);
}//end catch
}
//If no location found
else {
strLocation = "Unable to find location. ";
publishProgress(strLocation);
}
return strLocation;
}// end updateWithANewLocation()
@Override protected void onProgressUpdate(String... result) {
// TODO Auto-generated method stub
tvLocation.setText(result[0]);
}
}
答案 0 :(得分:3)
我做了一些快速搜索,但没有看到对运行异步的LocationManager的任何具体引用,但我的假设是,它以一种不影响UI性能的方式执行或调度,因为它是一个系统服务。
根据经验,我在主线程上获取位置并将其显示回用户没有任何问题。实际上,我计算了列表中大约100个项目的距离,而UI上没有明显的减速。后面的计算结果虽然我认为你应该考虑AsyncTask,因为它很容易影响性能。虽然也要注意AsyncTask任务和LocationManager位置更新间隔的更新时间。
根据每次调用updateWithANewLocation所花费的时间,您可能需要考虑将其放在后台任务上并将LocationManager保留在主线程上。
我假设您遇到问题的地方是LocationManager上的事件处理。以下内容应该对问题的这一部分有所了解:
调用线程必须是Looper 线程如主线程 调用Activity。
http://developer.android.com/reference/android/os/Looper.html
基本上当你的LocationAsyncTask完成执行时,它就消失了,所以事件回调发生在一个不再存在的线程上。 Looper会启动一个消息循环来接受那些LocationManager事件。
答案 1 :(得分:-7)
iOS SDK的核心位置提供CLLocationManager
对象,其中包含名为startUpdatingLocation
和startMonitoringSignificantLocationChanges
的实例方法,它们都是异步工作的。在调用其中一个之后,您只需实现回调locationManager:didUpdateToLocation:fromLocation
来处理位置更新。我打赌Android会做类似的事情。如果没有,请提交错误。