AsyncTask偶尔适用于Android

时间:2017-08-14 08:54:46

标签: android google-maps android-asynctask

我有一个MapsActivity在我的应用上显示Google地图。 我有一个文本文件,其中有街道名称,邮政编码和城市名称。我使用BufferedReader读取了这个文本文件。我的文本文件中有近100条街道。所以,我以编程方式在Google Map中添加了近100个标记。这需要时间,这取决于互联网连接。

因此我决定使用AsyncTask。我知道,在doInBackground中无法完成这些UI操作。我将readfile()方法(将这100个标记添加到doInBackground中)作为可运行的线程。我不希望用户看到空白屏幕,因此我添加了一个ProgressBar。

这就是问题所在:进度条总是不起作用,它并不总是被看到,它偶尔被看到,这让我认为我的Asycntask出了问题。也许我称之为AsyncTask的方式很糟糕。请看看我的代码。

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();

    }
}
}

1 个答案:

答案 0 :(得分:1)

所以,正如我在评论中所说,在这个例子中,基本上我重新编写了你的​​异步任务来在后台运行文件的读取,并在uithread中更新地图的进度。代码远非最终版,但您应该测试并改进它。

因为AsyncTask为您提供了更新uithreads的工具,所以不应该在那里使用runOnUiThread()

doc说:

  

AsyncTask可以正确,轻松地使用UI线程。这个班   允许您执行后台操作并在上面发布结果   UI线程,无需操纵线程和/或处理程序。

示例:

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;
}