【问题标题】:How to wait until onPostExecute finishes如何等到 onPostExecute 完成
【发布时间】:2026-01-25 05:45:02
【问题描述】:

所以我是编程新手,我想做的是制作一个 android 应用程序,为客户提供最近和最快的方式去电影院/加油站/市场。这样做的问题是,首先我需要通过 google api 找到最近的地方获取 lats 和 lngs,然后使用它们来指导 api。 所以我所做的是这样的:

GetNearbyPlaces.java

public class GetNearbyPlaces extends AsyncTask<Object, String, String>
{
private String googleplaceData, url;
private GoogleMap mMap;

@Override
protected String doInBackground(Object... objects)
{
    mMap = (GoogleMap) objects[0];
    url = (String) objects[1];

    DownloadUrl downloadUrl = new DownloadUrl();
    try
    {
        googleplaceData = downloadUrl.ReadTheURL(url);
    }

    catch (IOException e)
    {
        e.printStackTrace();
    }

    return googleplaceData;
}


@Override
protected void onPostExecute(String s)
{

    List<HashMap<String, String>> nearbyPlacesList = null;
    DataParser dataParser = new DataParser();
    nearbyPlacesList = dataParser.parse(s);
    DisplayNearbyPlaces(nearbyPlacesList);
    super.onPostExecute(s);
    Log.d("Message","telos execute ");

}

private void DisplayNearbyPlaces(List<HashMap<String, String>> nearbyPlacesList)
{
    for (int i=0; i<nearbyPlacesList.size(); 
       {
        Log.d("Message","mesa stin for ");
        MarkerOptions markerOptions = new MarkerOptions();
        HashMap<String, String> googleNearbyPlace = nearbyPlacesList.get(i);
        String nameOfPlace = googleNearbyPlace.get("place_name");
        String vicinity = googleNearbyPlace.get("vicinity");

        double lat = Double.parseDouble(googleNearbyPlace.get("lat"));
        double lng = Double.parseDouble(googleNearbyPlace.get("lng"));

        LatLng latLng = new LatLng(lat, lng);

        markerOptions.position(latLng);
        markerOptions.title(nameOfPlace + " : " + vicinity);
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW));
        mMap.addMarker(markerOptions);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(10));
    }

}

}

GoogleUserMaps.java

case R.id.gasstation_nearby:
            mMap.clear();
            mMap.addMarker(userLocMarkerOptions);
            mMap.setTrafficEnabled(true);

            url = getUrl(latitude,longitude,gasStation);
            transferData[0] = mMap;
            transferData[1] = url;

            Log.d("Message","Prin kanei execute ");
            getNearbyPlaces.execute(transferData);
            Log.d("Message","afou kanei execute ");


            Toast.makeText(this, "Searching for Nearby Gas Stations.", Toast.LENGTH_SHORT).show();
            Toast.makeText(this, "Showing for Nearby Gas Stations.", Toast.LENGTH_SHORT).show();
            break;

我想在 DisplayNearbyPlaces 中添加一些公共变量以获取 lats 和 lngs,但是当我在 getNearbyPlaces.execute(transferData).get(); 之后使用它时GoogleUserMaps.java 它给了我 0 结果。我无法理解 AsyncTask。有什么办法可以等到 getNearbyPlaces.execute(transferData).get();完成执行以获得 lats 和 lngs ?

提前谢谢你!

我的日志猫 I want to get the result after the execute finishes as I show you in the image bellow

【问题讨论】:

  • 不,我看到我无法正确理解这一点
  • 我能理解的是我应该把 private void DisplayNearbyPlaces(List> nearPlacesList) 的所有代码移到 onPostExecute 里面?
  • 其中一个答案明确指出不要使用 .get() 方法。
  • 结果是一样的,想得到getNearbyPlaces.execute(transferData);调用后的结果

标签: android asynchronous google-maps-api-3 android-asynctask


【解决方案1】:

异步任务在与 UI 线程不同的线程中运行。如果您尝试使用回调接口并且在调用异步任务的 onPost 时执行该回调中的操作会更好

【讨论】:

  • 感谢您的回答!可以举个例子吗?
  • 是的@Strack。为此,首先您必须创建一个接口,例如 PlacesListerner,其方法签名为 searchStarted();搜索结束();然后在您的活动中实现此接口,并在您的情况下通过 AsyncTask 中的构造函数传递其引用 GetNearbyPlaces ,然后在您的 asyncTask 调用 searchStarted() 的 preexcute 方法中显示一些进度条,并在 onPostExecute 调用中以您的接口引用结束。
  • 对不起,我是一个新手程序员,你能给我看一个代码示例吗?所以我需要创建private void PlaceListener(){ searchStarted(); searchEnded(); } ?
【解决方案2】:

@Strack 我正在发布接口的代码示例

`

public interface PlaceListener{
     void searchStarted();
     void searchEnded();

}



public class GetNearbyPlaces extends AsyncTask<Object, String, String>
{
private String googleplaceData, url;
private GoogleMap mMap;
private PlaceListener placeListener;

public GetNearbyPlaces(PlaceListener placeListener){
    this.placeListner = placeListener;
}

//onPreExecute(){ placeListner.searchStarted();}

@Override
protected String doInBackground(Object... objects)
{
    mMap = (GoogleMap) objects[0];
    url = (String) objects[1];

    DownloadUrl downloadUrl = new DownloadUrl();
    try
    {
        googleplaceData = downloadUrl.ReadTheURL(url);
    }

    catch (IOException e)
    {
        e.printStackTrace();
    }

    return googleplaceData;
}


@Override
protected void onPostExecute(String s)
{
    placeListner.serachEnded();
    List<HashMap<String, String>> nearbyPlacesList = null;
    DataParser dataParser = new DataParser();
    nearbyPlacesList = dataParser.parse(s);
    DisplayNearbyPlaces(nearbyPlacesList);
    super.onPostExecute(s);
    Log.d("Message","telos execute ");

}


}

`

在 Caller Activity 中实现 PlaceListener 并在 searchEnded 中执行您想要的任务。你可以根据你想要传递的数据来制作你的接口方法的参数

【讨论】:

  • 您必须在任务完成后调用 GoogleUserMaps 类的方法。
  • usermaps.doneWithListOfPoints();并在方法 doneWithListOfPoints(){ // Do something} 在 googleMap 类中
  • 我想从 GetNearbyPlaces.java 到 GoogleUserMaps.java 获取一个列表,但它返回 [] 因为它运行案例 R.id.gasstation_nearby: 在执行完成之前
【解决方案3】:

好的。创建一个新的回调:

public interface MyCallBack {
    void myTaskDone(List<HashMap<String, String>> nearbyPlacesList);
}

在您的活动中创建一个:

MyCallBack myCallBack = new MyCallBack() {
    @Override
    public void myTaskDone(List<HashMap<String, String>> nearbyPlacesList) {
        DisplayNearbyPlaces(nearbyPlacesList);
    }
};

发送对 Aynctask 的引用:

    getNearbyPlaces.execute(transferData, map, new MyCallBack() {
        @Override
        public void myTaskDone(List<HashMap<String, String>> nearbyPlacesList) {
            DisplayNearbyPlaces(nearbyPlacesList);
        }
    });

完整代码:

    public interface MyCallBack {
    void myTaskDone(List<HashMap<String, String>> nearbyPlacesList);
}

public class GetNearbyPlaces extends AsyncTask<Object, String, String> {
    private String googleplaceData;
    private String url;
    private GoogleMap mMap;
    private MyCallBack myCallBack;

    public GetNearbyPlaces(String url, GoogleMap mMap, MyCallBack myCallBack) {
        this.url = url;
        this.mMap = mMap;
        this.myCallBack = myCallBack;
    }

    @Override
    protected String doInBackground(Object... objects) {
        DownloadUrl downloadUrl = new DownloadUrl();
        try {
            googleplaceData = downloadUrl.ReadTheURL(url);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return googleplaceData;
    }


    @Override
    protected void onPostExecute(String s) {
        List<HashMap<String, String>> nearbyPlacesList = null;
        DataParser dataParser = new DataParser();
        nearbyPlacesList = dataParser.parse(s);
        myCallBack.myTaskDone(nearbyPlacesList);
    }

}

private void DisplayNearbyPlaces(List<HashMap<String, String>> nearbyPlacesList) {
    /// your code
}

MyCallBack myCallBack = new MyCallBack() {
    @Override
    public void myTaskDone(List<HashMap<String, String>> nearbyPlacesList) {
        DisplayNearbyPlaces(nearbyPlacesList); 
    }
};

如何称呼它:

    //.....
    transferData[0] = mMap;
    transferData[1] = url;

    Log.d("Message","Prin kanei execute ");
            GetNearbyPlaces getNearbyPlaces = new GetNearbyPlaces(transferData, map, myCallBack);
    getNearbyPlaces.execute();

    //or:

    GetNearbyPlaces getNearbyPlaces = new GetNearbyPlaces(transferData, map, new MyCallBack() {
        @Override
        public void myTaskDone(List<HashMap<String, String>> nearbyPlacesList) {
            DisplayNearbyPlaces(nearbyPlacesList);
        }
    });
    getNearbyPlaces.execute();

【讨论】:

    最近更新 更多