简体   繁体   中英

Google Maps v2 addPolygon() plugs up UI thread so my progress dialog doesn't animate

I am working on an application in which I would like to be able to load up to 10,000 polygons (40,000 lat/lng pairs) onto Google Maps v2 and the performance is mostly acceptable. But since it takes about 20 seconds to load, I need to have a progress indicator so it doesn't look like the app has locked up.

I believe the core issue is that the map.addPolygon(polygonOptions) call which I must repeat 10,000 times and must run on the UI thread plugs up the UI thread such that the progress dialog doesn't get any time to update it's UI. Here is an approximation of my code:

@Override
protected void onCreate(.....) {
    progressDialog = new ProgressDialog(AllLayersActivity.this);
    progressDialog.setMessage("Processing files:");
    progressDialog.setTitle("Loading data");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setProgress(0);
    progressDialog.setMax(1);
    progressDialog.show();
    progressDialog.incrementProgressBy(1);
    for(String filename : intent.getStringArrayListExtra(DbxService.PARAM_FILES)) {
        if(filename.toLowerCase(Locale.getDefault()).endsWith(".shp")) {
            dbxService.getFileContents(new DbxPath(pathToField + filename));
        }
    }
}

BroadcastReceiver for dbxService.getFileContents() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            byte[] fileContents = loadFromBroadcastIntent(.....);
            progressDialog.setMax(progressDialog.getMax() + getNumberOfParts(fileContents));
            // bunch of other processing
            for(Part part : getParts(fileContents) {
                final PolygonOptions polygonOptions = new PolygonOptions();
                // processing stuff
                polygonOptions.addAll(latLngList);
                runOnUiThread(new Runnable() {
                    public void run() {
                        map.addPolygon(polygonOptions);
                        progressDialog.incrementProgressBy(1);
                        if(progressDialog.getProgress() == progressDialog.getMax()) {
                            progressDialog.dismiss();
                        }
                    }
                });
            }
        }
    }).start();
}

I know that increasing the max of ProgressDialog on the fly probably looks kind of weird but I think it should work well in practice as the progressDialog.setMax(progressDialog.getMax() + parts); line runs many times less than the progressDialog.incrementProgressBy(1); lines, always adds more before the dialog could possibly falsely get to 100%, and should be increased to its final value quite quickly because the map.addPolygon(polygonOptions); line is by far the slowest thing I'm doing.

So, what can I do to allow the progress bar to animate nicely?

I would have just added this as a comment but I have under 50 rep so I can't yet. With that said I have an app that can add up to 10,000 Markers on the map and I run into the same issue. I tried adding the Markers in another thread but adding items to the map must be done in the UI thread which is the same thread as the progressDialog. So the short answer is No. If someone out there smarter than me knows of away to do this in an AsyncTask or Runnable then please LET ME KNOW TOO!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM