【问题标题】:Is there any way to call Geocoder.getFromLocation asynchronously?有什么方法可以异步调用 Geocoder.getFromLocation 吗?
【发布时间】:2013-11-13 09:28:59
【问题描述】:

我有一对坐标,我正在使用Geocoder.getFromLocation 来获取地址详细信息。但是这种方法是同步的,并且会冻结应用程序一段时间。我试图将它放在 AsyncTask 中,但我得到了一个 java.lang.IllegalStateException: Not on the main thread

有什么方法可以异步调用这个方法吗?

这是检索地址的方法(在 MapUtil 类中):

public static Address getAddress(Context context, Marker marker) {
    Geocoder geocoder = new Geocoder(context);
    Address address = null;
    try {
        List<Address> addressList = geocoder.getFromLocation(marker.getPosition().latitude, marker.getPosition().longitude, 1);

        if (addressList != null && addressList.size() > 0) {
            address = addressList.get(0);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return address;
}

这是我在 MainActivity 的 AsyncTask:

new AsyncTask<Void, Void, Void>() {
    Address address = null;

    @Override
    protected Void doInBackground(Void... params) {
        address = MapUtil.getAddress(MainActivity.this, marker);
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        System.out.println("Address = " + address);
    }
}.execute();

这是完整的堆栈跟踪:

11-13 06:36:12.423: W/System.err(17247): java.lang.IllegalStateException: Not on the main thread
11-13 06:36:12.423: W/System.err(17247):    at maps.aq.o.b(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at maps.ak.g.b(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at maps.af.bk.c(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at cpd.onTransact(SourceFile:80)
11-13 06:36:12.423: W/System.err(17247):    at android.os.Binder.transact(Binder.java:347)
11-13 06:36:12.423: W/System.err(17247):    at com.google.android.gms.maps.model.internal.d$a$a.getPosition(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at com.google.android.gms.maps.model.Marker.getPosition(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at com.example.util.MapUtil.getAddress(MapUtil.java:17)
11-13 06:36:12.423: W/System.err(17247):    at com.example.MainActivity$3.doInBackground(MainActivity.java:102)
11-13 06:36:12.423: W/System.err(17247):    at com.example.MainActivity$3.doInBackground(MainActivity.java:1)
11-13 06:36:12.423: W/System.err(17247):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-13 06:36:12.423: W/System.err(17247):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-13 06:36:12.423: W/System.err(17247):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-13 06:36:12.423: W/System.err(17247):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-13 06:36:12.423: W/System.err(17247):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-13 06:36:12.423: W/System.err(17247):    at java.lang.Thread.run(Thread.java:841)

【问题讨论】:

  • 请提供完整的堆栈跟踪。以及导致崩溃的代码。
  • @Snicolas 我刚刚添加了更多细节
  • 哎哟...问题不在于地理编码器方法,而是对 Marker.getPosition() 的调用。
  • 这就是你必须放入 doInBackground 的内容

标签: android geocoding google-maps-android-api-2 reverse-geocoding


【解决方案1】:

只是强调解决方案:

marker.getPosition() 的调用需要在主线程上执行。正如堆栈跟踪错误所说:

11-13 06:36:12.423: W/System.err(17247): java.lang.IllegalStateException: Not on the main thread
11-13 06:36:12.423: W/System.err(17247):    at maps.aq.o.b(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at maps.ak.g.b(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at maps.af.bk.c(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at cpd.onTransact(SourceFile:80)
11-13 06:36:12.423: W/System.err(17247):    at android.os.Binder.transact(Binder.java:347)
11-13 06:36:12.423: W/System.err(17247):    at com.google.android.gms.maps.model.internal.d$a$a.getPosition(Unknown Source)
11-13 06:36:12.423: W/System.err(17247):    at com.google.android.gms.maps.model.Marker.getPosition(Unknown Source)
...

因此,解决方案只是在调用 doInBackground() 之前获取位置,例如在我的 AsyncTask 中的 onPreExecute 方法上。我还更改了 getAddress() 方法以直接接收位置而不是标记。

new AsyncTask<Void, Void, Void>() {
    Address address = null;
    Position position = null;

    @Override
    protected Void doInBackground(Void... params) {
        position = marker.getPosition();
        address = MapUtil.getAddress(MainActivity.this, position);
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        System.out.println("Address = " + address);
    }
}.execute();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    • 2018-04-14
    相关资源
    最近更新 更多