0

我试图使用异步任务获取当前位置,此代码在没有异步任务的情况下工作正常,但是当我使用异步任务尝试它时,它显示 NO Location Found 并且抱歉没有找到地址。这是我的代码请帮助我提前感谢

public class MainActivity extends Activity {
/** Called when the activity is first created. */
String addressString;    
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
        new Getlocation().execute();    

}

// 异步任务的开始

class Getlocation extends AsyncTask<String, String, String> {


    ProgressDialog p;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub

       p = new ProgressDialog(MainActivity.this);                   
         p.setMessage("Please Wait Retrieving data..");     
         p.setTitle(" ");                                       
         p.setIcon(R.drawable.settings2);                       
         p.show();                                               
    }
    @Override
    protected String doInBackground(String... params) {
        Looper.prepare();

          LocationManager locationManager; 

            String context = Context.LOCATION_SERVICE; 
            locationManager = (LocationManager)getSystemService(context); 

            Criteria crta = new Criteria(); 
            crta.setAccuracy(Criteria.ACCURACY_FINE); 
            crta.setAltitudeRequired(false); 
            crta.setBearingRequired(false); 
            crta.setCostAllowed(true); 
            crta.setPowerRequirement(Criteria.POWER_LOW); 
            String provider = locationManager.getBestProvider(crta, true); 

         //String provider = LocationManager.GPS_PROVIDER; 
            Location location = locationManager.getLastKnownLocation(provider); 
            updateWithNewLocation(location); 
           LocationListener locationListener = new LocationListener() 
         { 

         @Override 
         public void onLocationChanged(Location location) { 
         updateWithNewLocation(location); 
         } 

         @Override 
         public void onProviderDisabled(String provider) { 
         updateWithNewLocation(null); 
         } 

         @Override 
         public void onProviderEnabled(String provider) { 
         } 

         @Override 
         public void onStatusChanged(String provider, int status, Bundle extras) { 
         } 

         };
         locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); 
         Looper.loop();

        return addressString;
    }
     @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result); 
            p.dismiss();                    

    }   }
 private void updateWithNewLocation(Location location) { 
     String latLong;
     TextView myLocation; 
      addressString = "Sorry  No Address Found"; 
     if(location!=null) { 
    double lat = location.getLatitude(); 
     double lon = location.getLongitude(); 
     latLong = "Lat:" + lat + "\nLong:" + lon; 
     double lattitude = location.getLatitude(); 
     double longitude = location.getLongitude(); 
     Geocoder gc = new Geocoder(this,Locale.getDefault()); 
     try { 
     List<Address> addresses= gc.getFromLocation(lattitude, longitude, 1); 
     StringBuilder sb = new StringBuilder(); 
     if(addresses.size()>0) { 
     Address address=addresses.get(0);
     for(int i=0;i<address.getMaxAddressLineIndex();i++)
     sb.append(address.getAddressLine(i)).append("\n");
     sb.append(address.getLocality()).append("\n"); 
     sb.append(address.getPostalCode()).append("\n"); 
     sb.append(address.getCountryName()); 

     } 
     addressString = sb.toString(); 
     } 
     catch (Exception e) { 
     } 
     } else { 
     latLong = " NO Location Found "; 
     } 
Toast.makeText(getApplicationContext(), "Current Position is :\n"+ latLong + "\n"+  addressString ,Toast.LENGTH_LONG).show();
  //  myLocation.setText("Current Position is :\n"+ latLong + "\n"+  addressString ); 
        }

}

//这是我的日志猫

    10-01 22:34:13.720: E/WindowManager(2868): Activity com.example.sc.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@411dd3c8 that was originally added here
10-01 22:34:13.720: E/WindowManager(2868): android.view.WindowLeaked: Activity com.example.sc.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@411dd3c8 that was originally added here
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:374)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
10-01 22:34:13.720: E/WindowManager(2868):  at android.view.Window$LocalWindowManager.addView(Window.java:547)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Dialog.show(Dialog.java:277)
10-01 22:34:13.720: E/WindowManager(2868):  at com.example.sc.MainActivity$Getlocation.onPreExecute(MainActivity.java:68)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.AsyncTask.execute(AsyncTask.java:534)
10-01 22:34:13.720: E/WindowManager(2868):  at com.example.sc.MainActivity.onCreate(MainActivity.java:51)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Activity.performCreate(Activity.java:5008)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 22:34:13.720: E/WindowManager(2868):  at android.os.Looper.loop(Looper.java:137)
10-01 22:34:13.720: E/WindowManager(2868):  at android.app.ActivityThread.main(ActivityThread.java:4745)
10-01 22:34:13.720: E/WindowManager(2868):  at java.lang.reflect.Method.invokeNative(Native Method)
10-01 22:34:13.720: E/WindowManager(2868):  at java.lang.reflect.Method.invoke(Method.java:511)
10-01 22:34:13.720: E/WindowManager(2868):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-01 22:34:13.720: E/WindowManager(2868):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-01 22:34:13.720: E/WindowManager(2868):  at dalvik.system.NativeStart.main(Native Method)
4

2 回答 2

1

这看起来像经典的“在非Looper线程中创建 Handler ”异常。基本上,您正在创建一个 Handler 来接收位置消息到您的 LocationListener 对象,该对象是在它自己的线程中创建的。doInBackground()一旦方法返回,运行的线程就会死掉。因此,LocationManager 正在向死线程中的死对象发送数据,并且您会遇到异常。

Loopers 的一个很好的示例在这里:

Looper 的目的是什么以及如何使用它?

如果放在Looper.prepare()顶部doInBackground()Looper.loop()底部,则可以继续使用 AsyncTask。 Looper.loop()只是一个空的 while 循环,它将使您的线程永远打开。

为了让它死掉,你必须在你的线程中调用 Looper.myLooper().quit() 来杀死它。 最简单的方法是立即Looper.prepare()通过调用 Looper.myLoop() 来保存 Looper。然后在要停止更新时调用的方法中将其杀死。

class LooperAsyncTask extends AsyncTask<Void, Void, Void> {

    private mThreadLooper;

    @Override
    protected String doInBackground(String... params) {
      Looper.prepare();
      mThreadLooper = Looper.myLooper();
      **setup code**
      Looper.loop();
    }

    public void stopUpdates() {
      **cleanup code**
      if(mThreadLooper != null)
        mThreadLooper.quit();
    }
}
于 2012-10-01T17:06:47.627 回答
0

您的 LocationManager 和 LocationListener 不需要在 AsyncTask 中。它们应该在 Activity 中(或者如果您想在 Activity 之间共享它们,则 Activity 引用的其他类)。

在 AsyncTask 中注册 LocationListener 不是正确的方法,因为该侦听器与 AsyncTask 一起死亡,因此不会在附近侦听更新。

顺便说一句,您的 updateWithNewLocation() 方法正在创建一个它没有使用的 TextView。

通过在 updateWithNewLocation() 中调用 Toast,您实际上是在不在 UI 线程上运行的doInBackground中调用它,因此,除非您在实例化 AsyncTask 时传入上下文,否则 Toast 的设置会很时髦。

如果这是一个缓慢的过程,那么当您的 Activity 捕获位置更改时,您可以在 AsyncTask 中反向地理编码,然后通过将 doInBackground 反向地理编码的结果传递给在 UI 线程上运行的onPostExecute来显示 Toast(或更新 TextView)因此可以安全轻松地更新视图并显示 Toast。

class ReverseGeocodeAsyncTask extends AsyncTask<Void, Void, Void> {

    private Location location;

    public ReverseGeocodeAsyncTask(Location l) { location = l; }

    @Override
    protected String doInBackground(String... params) {
     //do reverse geocoding and return the result
    }

     @Override
     protected void onPostExecute(String result) {
        // update the UI with the result of the reverse geocoding                   
    }
}
于 2012-10-01T17:33:18.463 回答