2

我担心在主线程上查找位置信息(使用反向地理编码)会减慢我的 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]);
            } 
        }
4

2 回答 2

3

我做了一些快速搜索,没有看到任何对异步运行的 LocationManager 的具体引用,但我的假设是它确实或它的调度方式不会影响 UI 性能,因为它是一个系统服务。

根据经验,我在主线程上获取位置并将其显示给用户没有问题。事实上,我计算了列表中大约 100 个项目的距离,而 UI 上没有明显的减速。后一种计算是我想说你应该考虑 AsyncTask 的地方,因为它很容易影响性能。尽管还要注意 AsyncTask 任务的时间长度和 LocationManager 位置更新的更新间隔。

根据每次调用 updateWithANewLocation 需要多长时间,您可能需要考虑将其放在后台任务上,并将 LocationManager 留在主线程上。

我假设您遇到的问题是 LocationManager 上的事件处理。以下内容应该对问题的这一部分提供一些见解:

http://developer.android.com/reference/android/location/LocationManager.html#requestLocationUpdates%28java.lang.String,%20long,%20float,%20android.location.LocationListener%29

调用线程必须是Looper线程,例如调用Activity的主线程。

http://developer.android.com/reference/android/os/Looper.html

基本上,当您的 LocationAsyncTask 完成执行时,它就消失了,因此事件回调正在发生在不再存在的线程上。Looper 将启动一个消息循环来接受那些 LocationManager 事件。

于 2011-04-17T03:03:48.827 回答
-7

iOS SDK 的核心位置提供了一个CLLocationManager对象,该对象具有调用的实例方法startUpdatingLocation,并且startMonitoringSignificantLocationChanges两者都是异步工作的。在调用其中之一之后,您只需实现回调locationManager:didUpdateToLocation:fromLocation来处理位置更新。我敢打赌Android会做类似的事情。如果没有,请提交错误。

于 2011-04-17T02:09:24.193 回答