我的Android应用程序中有MapActivity
,我想绘制从源到目的地的路线,然后沿找到的路径绘制polyline
。我正在显示progressDialog
,同时沿路径绘制polyline
。
我认为绘制折线是一项繁重的任务,因为它导致progressDialog
停止旋转。所以我将drawPolyline
功能放在AsyncTask
。
但我现在面临的问题是我没有更新屏幕,但突然MapActivity
屏幕闪烁并消失,我现在看到了MainActivity。
为什么会这样? 我想知道在AsyncTask的背景下更新UI是否在概念上是正确的?如果是,我们该如何去做呢?
注意:我已经通过放置breakPoints来检查AsyncTask功能。它按预期工作但drawPolyline导致错误。 另外drawPolyline没有问题,因为它在没有AsyncTask的情况下调用时工作正常。
这是我的AsyncTask代码:
public class DrawRoute {
private WeatherMapActivity listener;
private GoogleMap mMap = WeatherMapActivity.mMap;
private List<Step> stepsInThePath = WeatherMapActivity.stepsInThePath;
public DrawRoute(WeatherMapActivity listener) {
this.listener = listener;
Log.d("imHere", "in the DrawRouteConstructor");
}
public void execute(){
Log.d("imHere", "in the execute of DrawRoute");
new DrawPolyline().execute();
}
private class DrawPolyline extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
Log.d("imHere", "in the PreExecute");
}
@Override
protected Void doInBackground(Void... voids) {
Log.d("imHere", "in the Background");
Geocoder geocoder = new Geocoder(listener, Locale.getDefault());
mMap.addPolyline(new PolylineOptions()
.add(stepsInThePath.get(0).startLocation, stepsInThePath.get(0).endLocation)
.width(8)
.color(Color.RED));
mMap.addMarker(new MarkerOptions()
.title(MainActivity.sourceAddress)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.start_red))
.position(stepsInThePath.get(0).startLocation));
mMap.addMarker(new MarkerOptions()
.title(MainActivity.destinationAddress)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green))
.position(stepsInThePath.get(stepsInThePath.size()-1).endLocation));
for(int i=1; i < stepsInThePath.size(); i++){
mMap.addPolyline(new PolylineOptions()
.add(stepsInThePath.get(i-1).endLocation, stepsInThePath.get(i).endLocation)
.width(8)
.color(Color.RED));
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(stepsInThePath.get(i).startLocation.latitude, stepsInThePath.get(i).startLocation.longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String cityName = addresses.get(0).getLocality();
if(i%5 == 0 || i == stepsInThePath.size()-1){
mMap.addMarker(new MarkerOptions()
.title(cityName)
.position(stepsInThePath.get(i).startLocation));
}
}
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(stepsInThePath.get(0).startLocation, 5));
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
Log.d("imHere", "in the PostExecute");
// progressDialog.dismiss();
}
}
}
任何建议都将不胜感激。
谢谢!
答案 0 :(得分:1)
永远不要尝试直接从doInBackground()
方法更新UI元素。 doInBackground()
的目的是不通过在单独的线程中运行来从主线程(UI线程)卸载一些工作来阻止UI。
因此,从doInBackground()
开始,调用publishProgress()
将您的进度传递给onProgressUpdate()
函数以执行UI操作。
答案 1 :(得分:0)
doInBackground()
的{{1}}意味着在后台运行,除了MainThread 之外,没有其他线程可以更新用户界面。
你可以做什么在AsyncTask
进行所有计算并将其返回。然后画在doInBackground()
。或者您可以使用MainThread处理程序从onPostExecute()
进行绘制。
doInBackground()
OR
Handler mainHandler = new Handler(Looper.getMainLooper());