0

非同期タスクを使用して現在の場所を取得しようとしていますが、このコードは非同期タスクなしで正常に動作しますが、非同期タスクで試してみると、場所が見つかりませんとアドレスが見つかりませんでした。

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 ); 
        }

}

//ここに私のlogcatがあります

    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

これは、古典的な「非ルーパースレッドでの Handler の作成」例外のように見えます。基本的に、独自のスレッドで作成された LocationListener オブジェクトへの位置メッセージを受信するハンドラーを作成しています。実行中のスレッドはdoInBackground()、メソッドが戻るとすぐに終了します。したがって、LocationManager がデッド スレッド内のデッド オブジェクトにデータを送信すると、例外が発生します。

ルーパーの良いサンプルはここにあります:

Looper の目的と使用方法は何ですか?

Looper.prepare()上部doInBackground()と下部に配置すると、引き続き AsyncTask を使用できますLooper.loop()Looper.loop()スレッドを永久に開いたままにする空の while ループです。

終了するには、スレッドで Looper.myLooper().quit() を呼び出して終了する必要があります。 これを行う最も簡単な方法は、 の直後にLooper.prepare()、Looper.myLoop() を呼び出してルーパーを保存することです。次に、更新を停止するときに呼び出されるメソッドでそれを強制終了します。

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 にある必要はありません。それらはアクティビティ (または、アクティビティ間で共有する場合はアクティビティが参照する他のクラス) にある必要があります。

AsyncTask に LocationListener を登録することは正しいアプローチではありません。そのリスナーは AsyncTask で停止するため、更新をリッスンすることができないからです。

ちなみに、 updateWithNewLocation() メソッドは、使用していない TextView を作成しています。

updateWithNewLocation() で Toast を呼び出すことにより、UI スレッドで実行されていないdoInBackgroundで効果的に呼び出すことになるため、AsyncTask をインスタンス化するときにコンテキストを渡さない限り、Toast のセットアップがファンキーになります。

プロセスが遅い場合は、アクティビティが場所の変更をキャッチしたときに AsyncTask で逆ジオコードを実行し、UI スレッドで実行されるonPostExecuteに doInBackground 逆ジオコーディングの結果を渡すことで、トーストを表示 (または 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 に答える