所有AsyncTasks完成后,如何执行onMapReady()回调? [英] How to execute onMapReady() callback after all the AsyncTasks are completed?

查看:82
本文介绍了所有AsyncTasks完成后,如何执行onMapReady()回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在自己的代码中遇到了麻烦,我使用我的Activity来调用google api并检索json,将其反序列化并使用它的折线在地图上绘制.

I am having trouble with my code where i have my Activity which i use to call google api's and retrieve jsons, deserialize them and use it's Polylines to draw on the map.

问题在于,发送onMapReady()(用于创建地图)的回调的getMapAsync()在执行我的异步任务后立即执行,该任务检索了必要的数据以创建地图.

The problem is that getMapAsync() which sends the callback for onMapReady() (which is used to create the map) is executed immediately after executing my Async Tasks which retrieves necessary data to create the map.

如何在不停止UI线程的情况下做到这一点?我尝试执行此调用.execute.get(),它冻结了UI线程.但是,如果这样做,我将无法使用ProgressDialog通知用户有关从服务器获取数据的延迟,他们将被暴露在冻结的UI中,直到任务完成为止.我该怎么办?

How can i make this happen without stopping the UI thread? I tried doing this calling .execute.get() which freeze the UI thread. But if i do that, i won't be able to use ProgressDialog to inform the users about the delay for fetching data from the servers, which they will be exposed to a frozen UI until the task is complete. How can i do this?

public class RouteAssistantActivity extends Activity implements OnMapReadyCallback{

public GoogleMapsDirectionsResponse dirRes;
public GoogleMapsDistanceResponse disRes;

public String jsonString;
private String mapsAPIKey;
private String directionsBaseURL;
private String distanceBaseURL;

MapFragment mapFragment;
private ProgressDialog progress;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_ra_route_assisstant);

    mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.ra_map);
    progress = new ProgressDialog(RouteAssistantActivity.this);
    progress.setTitle("Please Wait");
    progress.setMessage("Retrieving Data from the Server");
    progress.setIndeterminate(true);

    try {
        ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);

        if (appInfo.metaData != null) {
            mapsAPIKey = appInfo.metaData.getString("com.google.android.maps.v2.API_KEY");
            directionsBaseURL = appInfo.metaData.getString("com.google.android.maps.directions.baseURL");
            distanceBaseURL = appInfo.metaData.getString("com.google.android.maps.distance.baseURL");
        }

    } catch (PackageManager.NameNotFoundException e) {
        Log.e("Meta Error", "Meta Data not found. Please check the Manifest and the Meta Data Package Names");
        e.printStackTrace();
    }

    //Test
    String directionsURL = directionsBaseURL+"origin=6.948109,79.858191&destination=6.910176,79.894347&key="+mapsAPIKey;
    String distanceURL = distanceBaseURL+"units=metric&origins=6.948109,79.858191&destinations=6.910176,79.894347&key="+mapsAPIKey;

    Log.e("CA Debug","URL : " + directionsURL);
    Log.e("CA Debug","URL : " + distanceURL);

    new configurationSyncTask().execute(distanceURL,"distance");
    new configurationSyncTask().execute(directionsURL, "direction");

    mapFragment.getMapAsync(this);

}

@Override
public void onMapReady(GoogleMap googleMap) {
    LatLng rajagiriya = new LatLng(6.910176, 79.894347);

    String points = dirRes.getRoutes().get(0).getOverviewPolyline();
    List<LatLng> list = PolyUtil.decode(points);

    googleMap.setMyLocationEnabled(true);
    googleMap.getUiSettings().setRotateGesturesEnabled(true);
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(rajagiriya, 13));

    googleMap.addMarker(new MarkerOptions()
            .title("Rajagiriya")
            .snippet("My Place")
            .position(rajagiriya));

    googleMap.addPolyline(new PolylineOptions()
            .geodesic(false)
            .addAll(list)
            .color(Color.RED)
            .width(25));
}

private class configurationSyncTask extends AsyncTask<String, Void, String> {

    @Override
    protected void onPreExecute() {
        progress.show();
    }

    @Override
    protected String doInBackground(String... params) {

        String url = params[0];
        String type = params[1];

        Log.d("CA Debug", getClass().getSimpleName() + " --> Real URL : " + url);
        Log.d("CA Debug", getClass().getSimpleName() + " --> doInBackground requesting content");

        jsonString = requestContent(url);

        // if the output is null, stop the current task
        if (jsonString == null) {
            Log.d("CA Debug", getClass().getSimpleName() + " --> Stopping Async Task");
            this.cancel(true);
            Log.d("CA Debug", getClass().getSimpleName() + " --> Async Task Stopped");
        }

        return type;
    }

    @Override
    protected void onPostExecute(String types) {

        if (types.equalsIgnoreCase("distance")) {
            disRes = GMapsDistanceResponseJSONDeserializer.deserialize(jsonString);
        } if (types.equalsIgnoreCase("directions")) {
            dirRes = GMapsDirectionsResponseJSONDeserializer.deserialize(jsonString);
        }

        progress.dismiss();
    }


}

public String requestContent(String url) {

    Log.d("CA Debug",getClass().getSimpleName()+" --> URL : "+url);

    try {
        URL urlObj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection();
        con.setChunkedStreamingMode(0);
        con.setRequestMethod("GET");

        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null,null, new SecureRandom());
        con.setSSLSocketFactory(sc.getSocketFactory());

        InputStream clientResponse;
        String jsonString;
        int status = con.getResponseCode();

        if(status >= HttpURLConnection.HTTP_BAD_REQUEST){
            Log.d("CA Debug", getClass().getSimpleName()+" --> Bad Request");
            jsonString = null;
        } else {
            Log.d("CA Debug", getClass().getSimpleName()+" --> converting Stream To String");
            clientResponse = con.getInputStream();
            jsonString = convertStreamToString(clientResponse);
        }

        Log.d("CA Debug", getClass().getSimpleName()+" --> JSON STRING : " + jsonString);

        return jsonString;
    } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {

        Log.d("CA Debug", getClass().getSimpleName()+" --> Error when creating an Input Stream");
        e.printStackTrace();

    }
    return null;
}

public String convertStreamToString(InputStream is) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line = null;

    try {
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
    } catch (IOException e) {
    } finally {
        try {
            is.close();
        } catch (IOException e) {
        }
    }

    return sb.toString();
}

}

推荐答案

快速且有些肮脏的解决方案是在单个AsyncTask上执行两个AsyncTask,然后在其onPostExecute代码上调用getMapAsync.这样,您可以确保在处理地图准备就绪之前完成任务.

Quick and somewhat dirty solution would be to execute both AsyncTasks on a single AsyncTask and then on its onPostExecute code invoke getMapAsync. this way you will be sure your tasks finished before you dealing with map's readyness.

这篇关于所有AsyncTasks完成后,如何执行onMapReady()回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆