简体   繁体   English

AsyncTask在Android上偶尔工作

[英]AsyncTask works sporadically Android

I have a MapsActivity to show Google Maps on my app. 我有一个MapsActivity,可在我的应用程序上显示Google Maps。 I have a text file where I have street names, zip codes and city names. 我有一个文本文件,其中有街道名称,邮政编码和城市名称。 I read this text file using BufferedReader. 我使用BufferedReader读取了此文本文件。 There are nearly 100 streets in my text file. 我的文本文件中有近100条街道。 So, I programmatically add nearly 100 markers in Google Map. 因此,我以编程方式在Google Map中添加了近100个标记。 That takes time, and it depends on the internet connection. 这需要时间,并且取决于互联网连接。

Therefore I decided to use AsyncTask. 因此,我决定使用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. 据我所知,UI事情无法在doInBackground完成, doInBackground我将readfile()方法(添加了这100个标记)作为可运行线程放在doInBackground中。 And I don't want the user to see a blank screen, therefore I added a ProgressBar. 而且我不希望用户看到空白屏幕,因此我添加了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. 问题就在这里: Progressbar并不总是有效,它并不总是可见,它是偶然可见的,这使我假设我的Asycntask有问题。 Maybe the way I call my AsyncTask is bad. 也许我称呼我的AsyncTask的方式不好。 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. 因此,正如我在评论中所说,在本示例中,基本上,我重新编写了异步任务,以在后台运行文件读取,并在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. 因为AsyncTask为您提供了更新uithread的工具,所以您永远不要在其中使用runOnUiThread()

The doc says: 医生说:

AsyncTask enables proper and easy use of the UI thread. 通过AsyncTask,可以正确,轻松地使用UI线程。 This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. 此类允许您执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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