我有一个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();
}
}
}
答案 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;
}