简体   繁体   中英

AsyncTask works sporadically Android

I have a MapsActivity to show Google Maps on my app. I have a text file where I have street names, zip codes and city names. I read this text file using BufferedReader. There are nearly 100 streets in my text file. So, I programmatically add nearly 100 markers in Google Map. That takes time, and it depends on the internet connection.

Therefore I decided to use AsyncTask. Since I know, that UI things cannot be done in doInBackground I put my readfile() method (which adds these 100 markers) in doInBackground as a runnable Thread. And I don't want the user to see a blank screen, therefore I added a ProgressBar.

And here is the problem: The Progressbar does not work always, it is not always to seen, it is sporadically to seen, which leds me to the assumption that something is wrong with my Asycntask. Maybe the way I call my AsyncTask is bad. Please have a look at my code.

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
String city, adress, zip;
LatLngBounds.Builder builder = new LatLngBounds.Builder();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    setContentView(R.layout.activity_maps);

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(map);
    mapFragment.getMapAsync(this);


}


@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    new Test().execute(null,null,null); //calling AsyncTask

}


public void readFile() {

    Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault());
    List<Address> address;
    LatLng p2;

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt")));
        String line;

        while ((line = reader.readLine()) != null) {

            String splittedLine[] = line.split(",");
            int numberofElements = 2;
            String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements);

            if ( address.size() !=0) {

                Address location = address.get(0);
                location.getLatitude();
                location.getLongitude();

                p2 = new LatLng(location.getLatitude(), location.getLongitude());

                mMap.addMarker(new MarkerOptions().position(p2).title("Location " + onlyAdressandZip[0]+"," + onlyAdressandZip[1]));
                builder.include(p2);

                LatLngBounds bounds = builder.build();
                mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20));

            }

              }

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

}


public class Test extends AsyncTask<Void, Void, Void>{
    ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // what to do before background task
        dialog = new ProgressDialog(MapsActivity.this);
        dialog.setTitle("Loading...");
        dialog.setMessage("Please wait.");
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }



    @Override
    protected Void doInBackground(Void... params) {
        runOnUiThread(new Runnable() {
            public void run() {

                readFile();

            }
        });
        return null;
    }

    @Override
    protected void onPostExecute(Void foo) {
    super.onPostExecute(foo);
    dialog.cancel();

    }
}
}

So, as I said in the comments, in this example, basically I re-wrote your async task to run the reading of the file in the background, and updating the progress of the map in the uithread. The code is far from final, but you should test and improve it.

Because an AsyncTask gives you the tools to update uithreads, you should never use runOnUiThread() in there.

The doc says:

AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

The example:

public class Test extends AsyncTask<Void, WrapperObject, Void> {
    ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // what to do before background task
        dialog = new ProgressDialog(MapsActivity.this);
        dialog.setTitle("Loading...");
        dialog.setMessage("Please wait.");
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }


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

        Geocoder coder = new Geocoder(MapsActivity.this, Locale.getDefault());
        List<Address> address;
        LatLng p2;

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("liste.txt")));
            String line;

            while ((line = reader.readLine()) != null) {

                String splittedLine[] = line.split(",");
                int numberofElements = 2;
                String[] onlyAdressandZip = Arrays.copyOf(splittedLine, numberofElements);

                if (address.size() != 0) {

                    Address location = address.get(0);
                    location.getLatitude();
                    location.getLongitude();

                    p2 = new LatLng(location.getLatitude(), location.getLongitude());
                    builder.include(p2);

                    WrapperObject wrapperObject = new WrapperObject();
                    wrapperObject.bounds = builder.build();
                    wrapperObject.latlng = p2;
                    wrapperObject.onlyAdressandZip = onlyAdressandZip;
                    publishProgress(wrapperObject);
                }

            }

        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    protected void onProgressUpdate(WrapperObject... wrapperObjects) {
        WrapperObject wrapperObject = wrapperObjects[0];
        mMap.addMarker(new MarkerOptions().position(wrapperObject.latlng).title("Location " + wrapperObject.onlyAdressandZip[0]+"," + wrapperObject.onlyAdressandZip[1]));
        mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(wrapperObject.bounds, 20));
    }

    @Override
    protected void onPostExecute(Void foo) {
        super.onPostExecute(foo);
        dialog.cancel();
    }
}
//this is a wrapper to update the progress, you should make this better.    
public static class WrapperObject {
    public LatLng latlng;
    public LatLngBounds bounds;
    public String[] onlyAdressandZip;
}

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